カスタムの公開フィルターを作成するにはどうすればよいですか?


7

Drupal 7のビュー3でカスタム公開フィルターを作成しようとしています

ビュー3とD7のカスタム公開フィルターを作成する方法についてどこで学ぶことができますか?

誰かが上のURLにコード例を入れましたが、それはビュー2にあるようです!?ビュー3で作成する方法を知っている人はいますか?

モジュール内:

/**
 * Implements hook_views_api().
 */
function modulename_views_api() {
  return array(
    'api' => 2,
    'path' => drupal_get_path('module', 'modulename') . '/inc',
  );
}

/**
 * Implementation of hook_views_handlers() to register all of the basic handlers
 * views uses.
 */
function modulename_views_handlers() {
  return array(
    'info' => array(
      // path to handler files
      'path' => drupal_get_path('module', 'modulename') . '/inc',
    ),
    'handlers' => array(
      // register our custom filter, with the class/file name and parent class
      'modulename_handler_filter_filtername' => array(
        'parent' => 'views_handler_filter',
      ),
    ),
  );
}

function modulename_views_data() {
  $data = array();

  $data['node']['filtername'] = array(
    'group' => t('Custom'),
    'real field' => 'my_custom_filter_field',
    'title' => t('My custom filter'),
    'help' => t('Some more detailed description if you need it.'),
    'filter' => array(
      'handler' => 'modulename_handler_filter_filtername',
    ),
  );

  return $data;
}

modulename_handler_filter_filtername.inc内

class modulename_handler_filter_filtername extends views_handler_filter {

  /**
   * Options form subform for setting exposed filter options.
   */
  function value_form(&$form, &$form_state) {
    parent::value_form($form, $form_state);

    // get list of years from database
    $query = db_select('node', 'n');
    $query->addExpression("FROM_UNIXTIME(n.created, '%Y')", 'year');
    if (isset($this->view->filter['type'])) {
      $query->condition('n.type', $this->view->filter['type']->value, 'IN');
    }
    $result = $query->orderBy('year', 'ASC')
      ->execute()
      ->fetchAllAssoc('year');

    $years = array(
      '0' => t('All'),
    );
    foreach ($result as $k => $v) {
      $years[$k] = $k;
    }

    // create form element with options retrieved from database
    $form['value']['year'] = array(
      '#type' => 'radios',
      '#options' => $years,
      '#default_value' => end($years),
    );
  }

  /**
   * Alters Views query when filter is used.
   */
  function query() {
    // make sure base table is included in the query
    $this->ensure_my_table();

    // retrieve real filter name from view options
    // this requires 'real field' filter option to be set (see code above)
    $real_field_name = $this->real_field;
    // get the value of the submitted filter
    $value = $this->view->exposed_data[$real_field_name];

    // finally, alter Views query
    if (is_numeric($value) && $value != 0) {
      /* 
        Having several custom exposed filters, make sure subsitution patterns
        (e.g. :filtername_value below) don't match across different filters.
        I spent some time figuring out why all my filters had the same value.
        It looks like the query skeleton is built first and then all replacements
        are made in bulk. Prefixing value with filter name looks good imo.
      */
      $this->query->add_where_expression($this->options['group'],
        "FROM_UNIXTIME(node.created, '%Y') = :filtername_value",
        array(':filtername_value' => $value));
    }
  }
}

回答:


12

ここにいくつかの例を提供するモジュールがあります:https : //www.drupal.org/project/views_plugin_examples。制限はありますが、公開されているフィルターの例があります。

ここでの一般的な議論:https : //api.drupal.org/api/views/views.api.php/group/views_plugins/7

概説すると:

  1. 「views」というサブディレクトリを持つカスタムモジュールを作成します。

  2. .infoファイルに次の行を追加し files[] = views/MODULE_handler_filter_FILTERNAME.incます。これを忘れると、フィルターは表示されません。

  3. .moduleファイルに、hook_views_api()の実装を追加します。

    function MODULE_views_api() {
      return array(
        'api' => 3,
        'path' => drupal_get_path('module', 'MODULE') . '/views',
      );
    }
  4. viewsサブディレクトリ内に、MODULE.views.incとMODULE_handler_filter_FILTERNAME.incの2つのファイルを作成する必要があります。

  5. MODULE.views.incでは、次のいずれかを実装する必要があります。

hook_views_data_alter()-ビュー統合が既に存在する既存のエンティティタイプの新しいフィルターの場合、より一般的ですOR

hook_views_data()-フィルターを含むカスタムエンティティのビュー統合を提供します。

APIドキュメントは、両方の関数で利用できます。

簡単な例:

    function MODULE_views_data_alter(&$data) {
       if ( isset($data['users']) && !isset($data['users']['FILTERNAME']) ) {
        $data['users']['FILTERNAME'] = array(
          'real field' => 'uid', // name of entity field to which filter applies
          'title' => t('HUMAN READABLE NAME OF FILTER'),
          'help' => t('HELP TEXT'),
          'filter' => array(
            'handler' => 'MODULE_handler_filter_FILTERNAME',
          ),
        );
      }
    }
  1. 実際の作業はすべて、MODULE_handler_filter_FILTERNAME.incで行われます。このファイルは、フィルターを実装する新しいクラス、クラスMODULE_handler_filter_FILTERNAMEを定義します。

通常、既存のビューフィルターハンドラークラスの1つを拡張して、既存のコードの利点を活用します。これらの多くは、ビューモジュールディレクトリのサブディレクトリにあります。基本的なフィルターは「handlers」サブディレクトリーにありますが、「modules」サブディレクトリーのサブディレクトリーに埋め込まれた、より複雑なフィルターが多数見つかります。見つけたビューフィルターハンドラーには、フィルターを実装する方法、および既存のフィルターを拡張する方法に関する最良のドキュメントがあり、それらを一読する必要があります。

通常、カスタムフィルタークラスは、a)拡張フィルターの設定フォームにフィールドを追加します。b)公開されたフィルターの場合、公開されたウィジェットを変更し、c)実際に機能するquery()メソッドを実装します。保存された設定と公開されたウィジェットからの入力。


1
このプロセスについてはウェブ上で多くの説明がありますが、最も明確で簡潔なため、常にこのプロセスに戻ります。
ブレイクフレデリック

0

同じ問題に遭遇し、それを理解しました、元の操作に同じ問題があるように見えます。

公開されたフィルターフォームをvalue_form()で定義する場合、配列で使用するキーは、view_data(またはviews_data_alter)で使用されるキーと同じでなければなりません。

例えば私の場合:

function value_form(&$form, &$form_state) {

  parent::value_form($form, $form_state);

  $form['users']['welcome_email_sent'] = array(
    '#type' => 'select',
    '#options' => array(
      0 => '- Any -',
      1 => 'Welcome Email',
      2 => 'Notification Email',

    ),
    '#title' => t('Email History'),
  );

  return $form;

}

そして..

function ca_email_history_views_data_alter(&$data) {

  $data['users']['welcome_email_sent'] = array(
    'title' => t('Welcome email sent'),
    'help' => t('Filter based on e-mails the user has received'),
    'filter' => array(
      'handler' => 'ca_email_history_welcome_email_sent_handler',
    ),
  );

  return $data;

}

query()関数が呼び出されないという問題と再度一致しないように変更すると、両方に「welcome_email_sent」というキーがあることに注意してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.