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


18

提供されたモジュール(選択またはその他)のカスタム公開フィルターを作成する方法を学習しようとしています。Drupal 6でこのチュートリアルを見つけましたが、Drupal 7ですぐに動作するようには見えません。

また、階層選択モジュールのコードを見てみましたが、私がやろうとしているものよりもはるかに複雑であるようです。

誰も私が学ぶことができる比較的簡単な方法で(たとえば、ロケーションモジュールのようなカスタムハンドラーの膨大な数ではない)カスタム公開されたフィルターを実装するチュートリアルやモジュールのための提案がありますか?

回答:


6

短い答え:どこにもありません。

しかし、あなたはあちこちで情報を見つけることができます。

最初に確認する場所は、Viewsソース、特に既存のフィルターの実装で、単純なフィルターから始めます。

個人的に、私はこのスレッドに参加しましたが、非常に有益でしたが、完全に満足のいくものではありませんでした。しかし、ここの情報は役に立つと思います。少なくとも、それが書かれた時点では正確だったと言えます。


2
ここでの会議で、私はちょうど発見したとの言及など、非常に有用な情報、含まれる最後のDrupalconからapi.drupal.orgのビューの一部、私は知りませんでしたドキュメントが。これは、私がこれまでに知っているViews開発の最適な出発点です。
カウントゼロ

10

私は同じ質問の答えを見つけようとしてインターネットの周りに潜んでいましたが、これは私が結果として得たものです:

  1. カスタムモジュールにいくつかのフックを実装します。modulenamefilternameを実際の名前に置き換えます。

    /**
     * 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;
    }
  2. incモジュールフォルダー内に名前の付いたフォルダーを作成し、modulename_handler_filter_filtername.incそこに名前の付いたファイルを作成します(このファイルの暗黙的な参照については、上記のコードを参照してください)。実際のモジュール名とフィルター名を使用することを忘れないでください。

  3. 次のコードをその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));
        }
      }
    }

最も簡単なカスタム公開フィルターを機能させるために必要なのはそれだけです!

クエリのFROM_UNIXTIME条件でSELECT使用すると、データベースが遅くなる可能性があることに注意してください。


最初:ありがとう!史上最高のガイド!、2番目:query()のより高度な使用法を探している人は、views_handler_filter_numeric.inc
hkoosha

また、次のように、クエリと置換を手動で記述する必要がない、より洗練された使用法があります$this->query->add_where($this->options['group'], $real_field_name, $this->value['value'], $this->operator);。上記のリンクにあります。
hkoosha 14年

2
Drupal 7では動作します。しかし、この作業を行うには、1)hook_views_handler関数の実装を削除し、2).infoファイルにこれを追加します。上のこの記事 4)多くの感謝!
ロジャー

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