Wo kann ich erfahren, wie Sie einen benutzerdefinierten belichteten Filter für Ansichten 3 und D7 erstellen?

18

Ich versuche zu lernen, wie man einen benutzerdefinierten belichteten Filter für ein beigesteuertes Modul (Auswahl oder anderes) erstellt. Ich habe dieses Tutorial für Drupal 6 gefunden, aber der Code scheint auf Drupal 7 nicht sofort zu funktionieren.

Ich habe auch versucht, den Code im hierarchischen Auswahlmodul zu betrachten, aber er scheint viel komplexer zu sein als das, was ich versuche.

Hat jemand Vorschläge für Tutorials oder Module, mit denen benutzerdefinierte Filter auf relativ einfache Weise implementiert werden (z. B. nicht viele benutzerdefinierte Handler wie das Standortmodul), von denen ich lernen kann?

Patrick Kenny
quelle

Antworten:

6

Kurze Antwort: Nirgendwo.

Aber hier und da gibt es Informationen.

Zunächst sollten Sie in Views-Quellen nachsehen, insbesondere nach der Implementierung vorhandener Filter, beginnend mit den einfacheren.

Persönlich habe ich an diesem Thread teilgenommen, der sehr lehrreich, aber nicht ganz zufriedenstellend war, wie Sie sehen werden, wenn Sie ihn lesen. Ich denke, die Informationen hier sind nützlich, und ich kann zumindest sagen, dass sie zu dem Zeitpunkt, als sie geschrieben wurden, genau waren.

Countzero
quelle
2
Hier ist eine Konferenz aus dem letzten Drupalcon, die ich gerade entdeckt habe und die unglaublich nützliche Informationen enthält, einschließlich der Erwähnung des Views-Teils der api.drupal.org- Dokumentation, von der ich nichts wusste. Dies ist der beste Ausgangspunkt für die Entwicklung von Views, die ich bisher kenne.
Countzero
10

Ich habe mich im Internet herumgetrieben und versucht, eine Antwort auf die gleiche Frage zu finden, und dies ist das Ergebnis, das ich erhalten habe:

  1. Implementieren Sie mehrere Hooks in Ihrem benutzerdefinierten Modul. Ersetzen Sie modulenameund filternamemit Ihren tatsächlichen Namen.

    /**
     * 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. Erstellen Sie einen Ordner mit dem Namen incin Ihrem Modulordner und erstellen Sie eine Datei mit dem Namen modulename_handler_filter_filtername.incdort (siehe obigen Code für einen impliziten Verweis auf diese Datei). Vergessen Sie nicht, die tatsächlichen Modul- und Filternamen zu verwenden.

  3. Füge folgenden Code in diese modulename_handler_filter_filtername.incDatei ein. Der Code, den ich für dieses Beispiel verwendet habe, erstellt eine Reihe von Optionsfeldern, die Jahre darstellen. So können Sie Knoten nach dem Erstellungsjahr filtern, wobei Sie nur die Jahre verwenden, in denen Knoten erstellt wurden.

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

Das ist alles, was Sie brauchen, um den einfachsten benutzerdefinierten belichteten Filter zum Laufen zu bringen!

Beachten Sie, dass die Verwendung von FROM_UNIXTIMEin SELECTAbfragezustand Ihre Datenbank verlangsamen kann.

ich bin komisch
quelle
zuerst: danke! der beste Leitfaden aller Zeiten !, zweitens: Für diejenigen, die eine erweiterte Verwendung von query () suchen
hkoosha
Es gibt auch eine elegantere Verwendung, bei der Sie die Abfrage und die Ersetzungen nicht manuell schreiben müssen, wie z $this->query->add_where($this->options['group'], $real_field_name, $this->value['value'], $this->operator);. Es kann im obigen Link gefunden werden.
Hkoosha
2
Es funktioniert für mich auf Drupal 7. Damit dies funktioniert, musste ich jedoch 1) die Implementierung der Funktion hook_views_handler löschen und 2) diese Datei zur INFO-Datei hinzufügen: files [] = inc / modulename_handler_filter_filtername.inc 3) diese beiden Änderungen habe ich zugrunde gelegt zu diesem Beitrag 4) Vielen Dank!
Roger