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

Простое решение: сначала создаем выпадающий список с нужными мета-значениями, затем обрабатываем отправку фильтра. Просто замените 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'];
}
}

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

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

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

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

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

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

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

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

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

Если вы используете другой запрос внутри 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'];
}
