Добавить фильтр меню в админ-список записей (произвольного типа) для фильтрации записей по значениям произвольных полей

13 мар. 2012 г., 16:27:30
Просмотры: 86.9K
Голосов: 56

Этот ответ очень близок к тому, что я хочу сделать, но вместо этого я хотел бы указать конкретное произвольное поле и отобразить выпадающее меню с его доступными значениями. Спасибо!

1
Комментарии

@soulseekah разве незаконно спросить направление, прежде чем пробовать что-то?

frnhr frnhr
14 сент. 2013 г. 16:33:06
Все ответы на вопрос 3
13
88

Простое решение: сначала создаем выпадающий список с нужными мета-значениями, затем обрабатываем отправку фильтра. Просто замените POST_TYPE на имя вашего типа записи и META_KEY на имя вашего мета-ключа:

<?php
/*
Plugin Name: Фильтр в админке по произвольным полям
Plugin URI: http://en.bainternet.info
Description: ответ на http://wordpress.stackexchange.com/q/45436/2487
Version: 1.0
Author: Bainternet
Author URI: http://en.bainternet.info
*/

add_action( 'restrict_manage_posts', 'wpse45436_admin_posts_filter_restrict_manage_posts' );
/**
 * Сначала создаем выпадающий список
 * убедитесь, что заменили POST_TYPE на имя вашего типа записи
 * 
 * @author Ohad Raz
 * 
 * @return void
 */
function wpse45436_admin_posts_filter_restrict_manage_posts(){
    $type = 'post';
    if (isset($_GET['post_type'])) {
        $type = $_GET['post_type'];
    }

    //добавляем фильтр только к нужному типу записи
    if ('POST_TYPE' == $type){
        //измените этот массив на список значений, которые нужно показать
        //в формате 'метка' => 'значение'
        $values = array(
            'метка' => 'значение', 
            'метка1' => 'значение1',
            'метка2' => 'значение2',
        );
        ?>
        <select name="ADMIN_FILTER_FIELD_VALUE">
        <option value=""><?php _e('Фильтровать по ', 'wose45436'); ?></option>
        <?php
            $current_v = isset($_GET['ADMIN_FILTER_FIELD_VALUE'])? $_GET['ADMIN_FILTER_FIELD_VALUE']:'';
            foreach ($values as $label => $value) {
                printf
                    (
                        '<option value="%s"%s>%s</option>',
                        $value,
                        $value == $current_v? ' selected="selected"':'',
                        $label
                    );
                }
        ?>
        </select>
        <?php
    }
}


add_filter( 'parse_query', 'wpse45436_posts_filter' );
/**
 * При отправке фильтруем по мета-полю
 * 
 * убедитесь, что заменили META_KEY на реальный мета-ключ
 * и POST_TYPE на имя вашего типа записи
 * @author Ohad Raz
 * @param  (wp_query object) $query
 * 
 * @return Void
 */
function wpse45436_posts_filter( $query ){
    global $pagenow;
    $type = 'post';
    if (isset($_GET['post_type'])) {
        $type = $_GET['post_type'];
    }
    if ( 'POST_TYPE' == $type && is_admin() && $pagenow=='edit.php' && isset($_GET['ADMIN_FILTER_FIELD_VALUE']) && $_GET['ADMIN_FILTER_FIELD_VALUE'] != '') {
        $query->query_vars['meta_key'] = 'META_KEY';
        $query->query_vars['meta_value'] = $_GET['ADMIN_FILTER_FIELD_VALUE'];
    }
}
13 мар. 2012 г. 17:02:23
Комментарии

Отлично! У меня возникли трудности с отображением этого на странице моего пользовательского типа записи (type=contestentry). Не могли бы вы проверить мой код в functions.php? Этот код взят из существующего плагина?

http://pastebin.com/BJMua8nq

adam5280 adam5280
13 мар. 2012 г. 17:57:23

Вы не изменили POST_TYPE здесь, попробуйте это: http://pastebin.com/tabUfh3Y

Bainternet Bainternet
13 мар. 2012 г. 18:02:06

Работает! Спасибо @Bainternet! Также пришлось изменить $type = 'post'; на строке 65. Ещё раз спасибо!

adam5280 adam5280
13 мар. 2012 г. 18:12:39

:) Единственное, что вам не нужно было менять, оно там по умолчанию, но это тоже нормально.

Bainternet Bainternet
13 мар. 2012 г. 18:22:05

Есть идеи, как полностью убрать фильтр "ПОКАЗАТЬ ВСЕ ДАТЫ", чтобы отображались только мои пользовательские фильтры для определенного типа записи?

RailsTweeter RailsTweeter
22 мая 2014 г. 20:04:04

@RailsTweeter задайте это как новый вопрос.

Bainternet Bainternet
23 мая 2014 г. 03:37:47

Это всё ещё лучший способ сделать это в WP 4?

mike23 mike23
11 сент. 2014 г. 12:40:53

@mike23 У меня есть несколько сайтов с таким же кодом, и всё по-прежнему работает отлично.

Bainternet Bainternet
11 сент. 2014 г. 15:42:45

Примечание: возможно, стоит убедиться, что код выполняется только для основного запроса $query->is_main_query()

jsweazy jsweazy
30 нояб. 2017 г. 20:09:18

СУПЕР КРУТО! Спасибо!!! Есть ли способ установить фильтр по умолчанию? Например, чтобы при открытии списка какой-то фильтр уже был выбран и список загружался с применением фильтра?

fdrv fdrv
9 февр. 2018 г. 19:52:07

Этот ответ отлично работает на WordPress 4.9.5! Решение хорошо сохранило актуальность, спасибо!

Davey Davey
11 апр. 2018 г. 14:22:41

Отличное решение! Спасибо!

Diego Somar Diego Somar
16 нояб. 2018 г. 20:37:38

Это опечатка или wose45436 намеренно отличается от wpse45436?

Pikamander2 Pikamander2
31 дек. 2021 г. 13:10:30
Показать остальные 8 комментариев
0

Если вы используете другой запрос внутри restrict_manage_posts, убедитесь, что добавили && $query->is_main_query() в ваше условие parse_query, иначе фильтр parse_query будет влиять на этот второй запрос.

if ( 'POST_TYPE' == $type
      && is_admin()
      && $pagenow=='edit.php'
      && isset($_GET['ADMIN_FILTER_FIELD_VALUE'])
      && $_GET['ADMIN_FILTER_FIELD_VALUE'] != ''
      && $query->is_main_query()
) {
      $query->query_vars['meta_key'] = 'META_KEY';
      $query->query_vars['meta_value'] = $_GET['ADMIN_FILTER_FIELD_VALUE'];
}
30 нояб. 2018 г. 20:06:15
0

Если вам нужно добавить много полей, их необходимо добавить в запрос

$query->query_vars['meta_query'][] = array(
    'key'     => 'KEY',
    'value'   => $_GET['FIELD'],
    'compare' => 'LIKE'
);
12 июл. 2019 г. 12:52:53