¿Dónde puedo obtener información sobre cómo crear un filtro expuesto personalizado para las Vistas 3 y D7?


18

Estoy tratando de aprender cómo crear un filtro expuesto personalizado para un módulo contribuido (select u otro). Encontré este tutorial para Drupal 6 pero el código no parece funcionar de fábrica en Drupal 7.

También intenté mirar el código en el módulo de selección jerárquica , pero parece ser mucho más complejo de lo que estoy tratando de hacer.

¿Alguien tiene alguna sugerencia para tutoriales o módulos que implementen filtros expuestos personalizados de una manera relativamente simple (por ejemplo, no una gran cantidad de controladores personalizados como el módulo de ubicación) de los que puedo aprender?

Respuestas:


6

Respuesta corta: en ninguna parte.

Pero puedes encontrar fragmentos de información aquí y allá.

El primer lugar para buscar es en las fuentes de Vistas, particularmente la implementación de filtros existentes, comenzando con los más simples.

Personalmente, participé en este hilo que fue muy instructivo pero no completamente satisfactorio, como verán si lo leen. Sin embargo, creo que la información aquí es útil, y al menos puedo decir que era precisa en el momento en que se escribió.


2
Aquí hay una conferencia del último Drupalcon que acabo de descubrir e incluye información increíblemente útil, incluida la mención de Vistas, parte de la documentación de api.drupal.org que no conocía. Este es el mejor punto de partida para el desarrollo de Vistas que conozco hasta ahora.
Countzero

10

Estaba acechando en Internet tratando de encontrar la respuesta a la misma pregunta y esto es lo que obtuve como resultado:

  1. Implemente varios ganchos en su módulo personalizado. Reemplace modulenamey filternamecon sus nombres reales.

    /**
     * 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. Cree una carpeta con nombre incdentro de la carpeta de su módulo y cree un archivo con nombre modulename_handler_filter_filtername.incallí (consulte el código anterior para obtener una referencia implícita a este archivo). No olvide usar el módulo real y los nombres de filtro.

  3. Pegue el siguiente código en ese modulename_handler_filter_filtername.incarchivo. El código que utilicé para este ejemplo crea un conjunto de botones de radio que presentan años. Por lo tanto, puede filtrar los nodos por año creado, utilizando solo los años en que se crearon los nodos.

    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));
        }
      }
    }

¡Eso es todo lo que necesita para que el filtro expuesto personalizado más simple funcione!

Tenga FROM_UNIXTIMEen cuenta que el uso en condiciones de SELECTconsulta puede ralentizar su base de datos.


primero: gracias! ¡la mejor guía! !, segundo: para aquellos que buscan un uso más avanzado de query (), ver views_handler_filter_numeric.inc
hkoosha

Además, hay un uso más elegante en el que no tiene que escribir la consulta y sustituciones de forma manual, como: $this->query->add_where($this->options['group'], $real_field_name, $this->value['value'], $this->operator);. Se puede encontrar en el enlace de arriba.
hkoosha

2
Me funciona en Drupal 7. Sin embargo, para que esto funcione tuve que 1) Eliminar la implementación de la función hook_views_handler y 2) Agregar esto al archivo .info: archivos [] = inc / modulename_handler_filter_filtername.inc 3) Basé estos dos cambios en esta publicación 4) Muchas gracias!
Roger

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.