Срабатывает перед кнопкой «Фильтр» в таблице записей админки. Позволяет добавить поля для фильтрации записей, страниц и произвольных типов записей.
Срабатывает перед кнопкой «Фильтр» в таблице записей админки. Позволяет добавить поля для фильтрации записей, страниц и произвольных типов записей.
Хук также работает в медиатеке в режиме списка.
Обработчик должен выводить HTML на экран, например через echo. Поля будут находится внутри существующей формы: создавать свою <form> не нужно. После нажатия «Фильтр» значения передаются в URL.
Хук только выводит элементы интерфейса. Чтобы произвольное поле влияло на выборку, нужно отдельно измените запрос через pre_get_posts или parse_query.
Для таксономии отдельный обработчик запроса не нужен, если имя поля совпадает с её query_var, а значения содержат слаги терминов.
add_action( 'restrict_manage_posts', 'wp_kama_restrict_manage_posts_action', 10, 2 );
/**
* Function for `restrict_manage_posts` action-hook.
*
* @param string $post_type The post type slug.
* @param string $which The location of the extra table nav markup: 'top' or 'bottom' for
* WP_Posts_List_Table, 'bar' for WP_Media_List_Table.
*
* @return void
*/
function wp_kama_restrict_manage_posts_action( $post_type, $which ){
// action...
}post, page, attachment или кастомный тип. Проверяйте его, чтобы выводить поля только на нужном экране.Расположение панели, в которой вызывается хук:
top - верхняя панель таблицы записей.bar - панель фильтров медиатеки в режиме списка.В документации также указано bottom, однако в текущем коде (WP 7.1) WP_Posts_List_Table::extra_tablenav() вызов этого хука находится внутри условия 'top' === $which. Поэтому снизу стандартной таблицы записей он не срабатывает.
Добавим два списка для типа записи book: по жанру genre и языку book_language. Тип записи и таксономии должны быть заранее зарегистрированы, таксономии связаны с book, а их query_var включён.
add_action( 'restrict_manage_posts', 'myplugin_book_taxonomy_filters', 10, 2 );
function myplugin_book_taxonomy_filters( $post_type, $which ) {
if ( 'book' !== $post_type || 'top' !== $which ) {
return;
}
foreach ( [ 'genre', 'book_language' ] as $taxonomy_name ) {
$taxonomy = get_taxonomy( $taxonomy_name );
if ( ! $taxonomy || ! $taxonomy->query_var ) {
continue;
}
$name = $taxonomy->query_var;
$selected = sanitize_text_field( wp_unslash( $_GET[ $name ] ?? '' ) ) ?: '';
wp_dropdown_categories( [
'taxonomy' => $taxonomy_name,
'name' => $name,
'id' => "filter-{$name}",
'show_option_all' => $taxonomy->labels->all_items,
'value_field' => 'slug',
'selected' => $selected,
'orderby' => 'name',
'hierarchical' => true,
'hide_empty' => false,
] );
}
}Здесь name берётся из $taxonomy->query_var: он может отличаться от названия таксономии.
Добавим фильтр книг по метаполю reading_status, в котором хранятся значения planned или finished.
add_action( 'restrict_manage_posts', 'myplugin_book_status_filter', 10, 2 );
add_action( 'pre_get_posts', 'myplugin_filter_books_by_status' );
function myplugin_book_status_filter( $post_type, $which ) {
if ( 'book' !== $post_type || 'top' !== $which ) {
return;
}
$value = sanitize_key( wp_unslash( $_GET['book_status'] ?? '' ) ) ?: '';
$options = [
'' => __( 'Все статусы чтения', 'myplugin' ),
'planned' => __( 'В планах', 'myplugin' ),
'finished' => __( 'Прочитано', 'myplugin' ),
];
$options = [];
foreach ( $options as $key => $label ) {
$options[] = sprintf(
'<option value="%s"%s>%s</option>',
esc_attr( $key ),
selected( $value, $key, false ),
esc_html( $label )
);
}
echo '<select name="book_status" id="book-status">' . implode( "\n", $options ) . '</select>';
}
function myplugin_filter_books_by_status( $query ) {
if (
! is_admin()
|| 'edit.php' !== ( $GLOBALS['pagenow'] ?? '' )
|| ! $query->is_main_query()
|| 'book' !== $query->get( 'post_type' )
) {
return;
}
$value = sanitize_key( wp_unslash( $_GET['book_status'] ?? '' ) ) ?: '';
if ( ! in_array( $value, [ 'planned', 'finished' ], true ) ) {
return;
}
$meta_query = [
'relation' => 'AND',
[
'key' => 'reading_status',
'value' => $value,
],
];
$existing = $query->get( 'meta_query' );
if ( $existing ) {
$meta_query[] = $existing;
}
$query->set( 'meta_query', $meta_query );
}Существующий meta_query сохраняется отдельной группой, поэтому его внутренние связи AND/OR не меняются. Подробнее об условиях метаполей: WP_Meta_Query{}.
Если варианты ($options) заранее неизвестны, список можно сформировать из уникальных значений метаполя:
global $wpdb;
$values = $wpdb->get_col( $wpdb->prepare("
SELECT DISTINCT pm.meta_value
FROM {$wpdb->postmeta} AS pm
INNER JOIN {$wpdb->posts} AS p ON (p.ID = pm.post_id)
WHERE pm.meta_key = %s
AND p.post_type = %s
AND p.post_status IN ( 'publish', 'draft' )
AND pm.meta_value != ''
ORDER BY pm.meta_value ASC",
'reading_status',
'book'
) );
$options = [
'' => __( 'Все статусы чтения', 'myplugin' ),
];
foreach ( $values as $value ) {
$options[ $value ] = $value;
}| # | Наименование новости | Тональность | Информативность | Дата публикации |
|---|---|---|---|---|
| 1 | Хук-Фильтр WordPress: post_type_link | 0 | 21.11 | 21-09-2026 |
| 2 | Хук-Фильтр WordPress: get_the_excerpt | 0 | 19.09 | 22-09-2026 |
| 3 | Хук-Фильтр WordPress: the_category | 0 | 19.09 | 20-09-2026 |
| 4 | Хук-Фильтр WordPress: wp_title | 0 | 18.33 | 20-09-2026 |
| 5 | Хук-Фильтр WordPress: paginate_links | 0 | 17.69 | 20-09-2026 |
| 6 | Хук-событие WordPress: edit_post_(post_type) | 0 | 18.33 | 22-09-2026 |
| 7 | Хук-событие WordPress: in_widget_form | 0 | 16.25 | 20-09-2026 |
| 8 | Хук-событие WordPress: network_admin_edit_(action) | 0 | 21.16 | 01-10-2026 |
| 9 | Хук-событие WordPress: admin_init | 0 | 23.68 | 20-09-2026 |
| 10 | Хук-Фильтр WordPress: excerpt_length | 0 | 19.41 | 20-09-2026 |