Dove posso imparare come creare un filtro esposto personalizzato per Views 3 e D7?


18

Sto cercando di imparare come creare un filtro esposto personalizzato per un modulo contribuito (selezionare o altro). Ho trovato questo tutorial per Drupal 6 ma il codice non sembra funzionare immediatamente su Drupal 7.

Ho anche provato a guardare il codice nel modulo di selezione gerarchico, ma sembra essere molto più complesso di quello che sto cercando di fare.

Qualcuno ha qualche suggerimento per tutorial o moduli che implementano filtri esposti personalizzati in un modo relativamente semplice (ad esempio, non un numero enorme di gestori personalizzati come il modulo di localizzazione) da cui posso imparare?

Risposte:


6

Risposta breve: da nessuna parte.

Ma puoi trovare alcune informazioni qua e là.

Il primo posto da guardare è nelle fonti di Views, in particolare l'implementazione di filtri esistenti, a partire da quelli più semplici.

Personnaly, ho partecipato a questo thread che è stato molto istruttivo ma non completamente soddisfacente, come vedrai se vai a leggerlo. Penso che le informazioni qui siano utili, e posso almeno dire che erano accurate al momento in cui sono state scritte.


2
Ecco una conferenza dell'ultimo Drupalcon che ho appena scoperto e include informazioni incredibilmente utili, inclusa la menzione della parte di Views della documentazione di api.drupal.org che non conoscevo. Questo è il miglior punto di partenza per lo sviluppo di Views che conosco finora.
Countzero,

10

Ero in agguato su Internet cercando di trovare la risposta per la stessa domanda e questo è ciò che ho ottenuto in risultato:

  1. Implementa diversi hook nel tuo modulo personalizzato. Sostituisci modulenamee filternamecon i tuoi nomi attuali.

    /**
     * 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. Crea una cartella denominata incnella cartella del tuo modulo e crea il file chiamato modulename_handler_filter_filtername.inclì (vedi il codice sopra per riferimento implicito a questo file). Non dimenticare di utilizzare i nomi dei moduli e dei filtri attuali.

  3. Incolla il seguente codice in quel modulename_handler_filter_filtername.incfile. Il codice che ho usato per questo esempio crea una serie di pulsanti di opzione che presentano anni. Quindi puoi filtrare i nodi per anno di creazione, usando solo gli anni in cui i nodi sono stati creati.

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

Questo è tutto ciò che serve per far funzionare il filtro esposto personalizzato più semplice!

Si noti che l'utilizzo FROM_UNIXTIMEin condizioni di SELECTquery potrebbe rallentare il database.


primo: grazie! la migliore guida di sempre !, secondo: per coloro che sono alla ricerca di un uso più avanzato di query (), vedere views_handler_filter_numeric.inc
hkoosha,

Inoltre, v'è un uso più elegante in cui non c'è bisogno di scrivere la query e sostituzioni manualmente, come: $this->query->add_where($this->options['group'], $real_field_name, $this->value['value'], $this->operator);. Può essere trovato nel link sopra.
hkoosha,

2
Funziona per me su Drupal 7. Tuttavia, per farlo funzionare ho dovuto 1) Eliminare l'implementazione della funzione hook_views_handler e 2) Aggiungere questo al file .info: files [] = inc / modulename_handler_filter_filtername.inc 3) Ho basato queste due modifiche su questo post 4) Mille grazie!
Roger,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.