Wie erstelle ich einen benutzerdefinierten exponierten Filter?

7

Ich versuche, in Ansichten 3 von Drupal 7 einen benutzerdefinierten exponierten Filter zu erstellen

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

Jemand hat ein Codebeispiel in die obige URL eingefügt, aber es scheint, dass es in Ansichten 2 ist!? Weiß jemand, wie man es in Ansichten 3 macht.

Im Modul:

/**
 * 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;
}

In 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));
    }
  }
}
Kenpeter
quelle

Antworten:

12

Es gibt ein Modul, das hier einige Beispiele enthält: https://www.drupal.org/project/views_plugin_examples . Es ist begrenzt, hat aber ein Beispiel für einen exponierten Filter.

Allgemeine Diskussion hier: https://api.drupal.org/api/views/views.api.php/group/views_plugins/7

In groben Zügen:

  1. Erstellen Sie ein benutzerdefiniertes Modul mit einem Unterverzeichnis namens "Ansichten".

  2. Fügen Sie in Ihrer .info-Datei eine Zeile hinzu: files[] = views/MODULE_handler_filter_FILTERNAME.incIhr Filter wird nie angezeigt, wenn Sie dies vergessen!

  3. Fügen Sie in der .module-Datei eine Implementierung von hook_views_api () hinzu:

    function MODULE_views_api() {
      return array(
        'api' => 3,
        'path' => drupal_get_path('module', 'MODULE') . '/views',
      );
    }
  4. Innerhalb des Views-Unterverzeichnisses müssen Sie zwei Dateien erstellen, MODULE.views.inc und MODULE_handler_filter_FILTERNAME.inc

  5. In MODULE.views.inc müssen Sie Folgendes implementieren:

hook_views_data_alter () - für einen neuen Filter für einen vorhandenen Entitätstyp, der bereits über eine View-Integration verfügt, was häufiger vorkommt

hook_views_data () - um die Integration von Ansichten für Ihre benutzerdefinierte Entität einschließlich Filtern bereitzustellen.

Für beide Funktionen steht eine API-Dokumentation zur Verfügung.

Ein kurzes Beispiel:

    function MODULE_views_data_alter(&$data) {
       if ( isset($data['users']) && !isset($data['users']['FILTERNAME']) ) {
        $data['users']['FILTERNAME'] = array(
          'real field' => 'uid', // name of entity field to which filter applies
          'title' => t('HUMAN READABLE NAME OF FILTER'),
          'help' => t('HELP TEXT'),
          'filter' => array(
            'handler' => 'MODULE_handler_filter_FILTERNAME',
          ),
        );
      }
    }
  1. Die gesamte eigentliche Arbeit findet in MODULE_handler_filter_FILTERNAME.inc statt. Diese Datei definiert eine neue Klasse, die Ihren Filter implementiert, die Klasse MODULE_handler_filter_FILTERNAME.

Normalerweise möchten Sie eine der vorhandenen Filterhandlerklassen für Ansichten erweitern, um den vorhandenen Code nutzen zu können. Viele davon befinden sich in Unterverzeichnissen des Verzeichnisses des Ansichtsmoduls. Die Grundfilter befinden sich im Unterverzeichnis "Handler", aber viele komplexere Filter befinden sich möglicherweise in Unterverzeichnissen des Unterverzeichnisses "Module". Die Filter-Handler für Ansichten, die Sie dort finden, sind die beste Dokumentation zum Implementieren eines Filters sowie zum Erweitern eines vorhandenen Filters. Sie sollten sie durchlesen.

Normalerweise fügt Ihre benutzerdefinierte Filterklasse a) Felder zum Einstellungsformular des erweiterten Filters hinzu, b) im Fall eines exponierten Filters das exponierte Widget, und c) implementiert eine query () -Methode, die die eigentliche Arbeit basierend auf erledigt die gespeicherten Einstellungen und Eingaben vom belichteten Widget.

Giles B.
quelle
1
Es gibt viele Erklärungen im Internet zu diesem Prozess, aber ich komme immer wieder auf diesen zurück, weil er am klarsten und prägnantesten ist.
Blake Frederick
0

Bin auf das gleiche Problem gestoßen und habe es herausgefunden. Es sieht so aus, als ob die ursprüngliche Operation das gleiche Problem hat.

Wenn Sie Ihr offengelegtes Filterformular in value_form () definieren, sollte der Schlüssel, den Sie im Array verwenden, derselbe Schlüssel sein, der in view_data (oder views_data_alter) verwendet wird.

zB in meinem Fall:

function value_form(&$form, &$form_state) {

  parent::value_form($form, $form_state);

  $form['users']['welcome_email_sent'] = array(
    '#type' => 'select',
    '#options' => array(
      0 => '- Any -',
      1 => 'Welcome Email',
      2 => 'Notification Email',

    ),
    '#title' => t('Email History'),
  );

  return $form;

}

Und..

function ca_email_history_views_data_alter(&$data) {

  $data['users']['welcome_email_sent'] = array(
    'title' => t('Welcome email sent'),
    'help' => t('Filter based on e-mails the user has received'),
    'filter' => array(
      'handler' => 'ca_email_history_welcome_email_sent_handler',
    ),
  );

  return $data;

}

Beachten Sie, dass beide den Schlüssel 'welcome_email_sent' haben, wenn ich sie so ändere, dass sie nicht mehr mit dem Problem übereinstimmen, bei dem die query () -Funktion nie wieder aufgerufen wird.

Täuschen
quelle