Di mana saya dapat belajar tentang cara membuat filter terpapar khusus untuk Tampilan 3 dan D7?

18

Saya mencoba mempelajari cara membuat filter terpapar khusus untuk modul yang disumbangkan (pilih atau lainnya). Saya menemukan tutorial ini untuk Drupal 6 tetapi kode tersebut tidak terlihat bekerja di luar kotak pada Drupal 7.

Saya juga mencoba melihat kode dalam modul pilih hirarkis tetapi tampaknya jauh lebih kompleks daripada apa yang saya coba lakukan.

Adakah yang punya saran untuk tutorial atau modul yang menerapkan filter terpapar khusus dengan cara yang relatif sederhana (mis., Tidak banyak penangan kustom seperti modul lokasi) yang dapat saya pelajari?

Patrick Kenny
sumber

Jawaban:

6

Jawaban singkat: tidak ada tempat.

Tetapi Anda dapat menemukan bit informasi di sana-sini.

Tempat pertama untuk melihat adalah di sumber Views, khususnya penerapan filter yang ada, dimulai dengan yang lebih sederhana.

Personnaly, saya berpartisipasi dalam utas ini yang sangat instruktif tetapi tidak sepenuhnya memuaskan, seperti yang akan Anda lihat jika Anda membacanya. Saya pikir info di sini berguna, dan saya setidaknya bisa mengatakan itu akurat pada saat itu ditulis.

Countzero
sumber
2
Ini adalah konferensi dari Drupalcon terakhir yang baru saja saya temukan dan menyertakan informasi yang sangat berguna, termasuk penyebutan bagian Tampilan dokumentasi api.drupal.org yang tidak saya ketahui. Ini adalah tempat awal terbaik untuk pengembangan Tampilan yang saya ketahui sejauh ini.
Countzero
10

Saya bersembunyi di internet mencoba menemukan jawaban untuk pertanyaan yang sama dan inilah yang saya dapatkan sebagai hasilnya:

  1. Terapkan beberapa kait dalam modul khusus Anda. Ganti modulenamedan filternamedengan nama Anda yang sebenarnya.

    /**
     * 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. Buat folder bernama incdi dalam folder modul Anda dan buat file bernama di modulename_handler_filter_filtername.incsana (lihat kode di atas untuk referensi implisit ke file ini). Jangan lupa untuk menggunakan nama modul dan filter yang sebenarnya.

  3. Rekatkan kode berikut ke dalam modulename_handler_filter_filtername.incfile itu. Kode yang saya gunakan untuk contoh ini membuat satu set tombol radio yang hadir tahun. Jadi, Anda dapat memfilter node menurut tahun, hanya menggunakan tahun saat node dibuat.

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

Hanya itu yang Anda butuhkan agar filter terpajan kustom yang paling sederhana bekerja!

Perhatikan bahwa penggunaan FROM_UNIXTIMEdalam kondisi SELECTkueri dapat memperlambat basis data Anda.

saya aneh
sumber
pertama: terima kasih! panduan terbaik yang pernah ada !, kedua: bagi mereka yang mencari penggunaan kueri yang lebih maju (), lihat views_handler_filter_numeric.inc
hkoosha
Juga, ada penggunaan lebih elegan di mana Anda tidak harus menulis query dan substitusi secara manual, seperti: $this->query->add_where($this->options['group'], $real_field_name, $this->value['value'], $this->operator);. Itu dapat ditemukan di tautan di atas.
hkoosha
2
Ini berfungsi untuk saya di Drupal 7. Namun, untuk membuat pekerjaan ini saya harus 1) Hapus implementasi fungsi hook_views_handler dan 2) Tambahkan ini ke file .info: file [] = inc / modulename_handler_filter_filtern_filtername.inc 3) Saya mendasari dua perubahan ini pada posting ini 4) Banyak terima kasih!
Roger