Де я можу дізнатись про те, як створити спеціальний відкритий фільтр для переглядів 3 та D7?


18

Я намагаюся дізнатися, як створити спеціальний підданий фільтр для внесеного модуля (вибору або іншого). Я знайшов цей підручник для Drupal 6, але, схоже, код не працює на Drupal 7.

Я також спробував подивитися на код в ієрархічному модулі вибору, але він здається набагато складнішим, ніж те, що я намагаюся зробити.

Хтось має пропозиції щодо навчальних посібників або модулів, які реалізують власні відкриті фільтри порівняно просто (наприклад, не величезна кількість користувацьких обробників, таких як модуль розташування), з яких я можу навчитися?

Відповіді:


6

Коротка відповідь: нікуди.

Але ви можете знайти шматочки інформації тут і там.

Перше місце, на яке слід звернути увагу, - це джерела Views, зокрема реалізація існуючих фільтрів, починаючи з більш спрощених.

Персонналі, я брав участь у цій темі, яка була дуже повчальною, але не зовсім задовільною, як ви побачите, чи читаєте ви її. Я думаю, що тут інформація є корисною, і я, принаймні, можу сказати, що вона була гострою під час її написання.


2
Ось конференція з останнього Drupalcon, яку я щойно відкрив, і містить неймовірно корисну інформацію, включаючи згадку про частину переглядів документації api.drupal.org, про яку я не знав. Це найкраще вихідне місце для розробки переглядів, про які я знаю дотепер.
Графзеро

10

Я ховався по Інтернету, намагаючись знайти відповідь на те саме питання, і ось що я отримав у результаті:

  1. Вставте кілька гачків у свій спеціальний модуль. Замініть modulenameі filternameвласними іменами.

    /**
     * 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_UNIXTIMEв умовах SELECTзапиту може уповільнити вашу базу даних.


перше: спасибі! найкращий посібник коли-небудь! Другий: для тих, хто шукає більш досконалого використання запиту (), дивіться views_handler_filter_numeric.inc
hkoosha

Крім того , є більш елегантне використання , де ви не повинні написати запит і заміну вручну, наприклад: $this->query->add_where($this->options['group'], $real_field_name, $this->value['value'], $this->operator);. З ним можна ознайомитися за вищенаведеним посиланням.
hkoosha

2
Це працює для мене на Drupal 7. Однак, щоб виконати цю роботу, мені довелося 1) Видалити реалізацію функції mock_views_handler і 2) Додати це у файл .info: files [] = inc / modulename_handler_filter_filtername.inc 3) Я базував ці дві зміни на цій посаді 4) Велике спасибі!
Роджер

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.