在哪里可以了解如何为Views 3和D7创建自定义的公开滤镜?


18

我正在尝试学习如何为贡献的模块(选择或其他)创建自定义的公开过滤器。我在Drupal 6上找到了本教程,但是该代码似乎在Drupal 7上无法立即使用。

我还尝试查看了层次选择模块中的代码,但它似乎比我想做的要复杂得多。

有没有人对我可以从中学习的教程或模块提出任何建议,这些教程或模块以相对简单的方式(例如,位置模块等数量不多的自定义处理程序)实现了自定义暴露的过滤器?

Answers:


6

简短答案:无处。

但是您可以在这里和那里找到一些信息。

首先要查看的是Views源代码,尤其是现有过滤器的实现,从较简单的过滤器开始。

从个人角度来说,我参加了这个非常有启发性但并不完全令人满意的话题,因为您会看到是否读过它。我认为这里的信息很有用,我至少可以说在撰写本文时是准确的。


2
这是我刚刚发现的上一个Drupalcon 的会议,其中包含了非常有用的信息,其中包括我不知道的api.drupal.org文档的Views部分。到目前为止,这是我所了解的Views开发的最佳起点。
Countzero 2012年

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_UNIXTIMESELECT查询条件下使用可能会降低数据库速度。


第一:谢谢!有史以来最好的指南!第二:对于那些正在寻求更高级使用query()的用户,请查看views_handler_filter_numeric.inc
hkoosha 2014年

此外,还有一种更优雅的用法,您不必手动编写查询和替换内容,例如:$this->query->add_where($this->options['group'], $real_field_name, $this->value['value'], $this->operator);。可以在上面的链接中找到。
hkoosha 2014年

2
它在Drupal 7上对我有效。但是,要完成此工作,我必须:1)删除hook_views_handler函数的实现,以及2)将其添加到.info文件:files [] = inc / modulename_handler_filter_filtername.inc 3)我基于这两个更改在这篇文章 4)非常感谢!
罗杰(Roger)2015年

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.