Как отсортировать область администрирования пользовательского типа записи WordPress по пользовательскому полю
При редактировании одного из моих пользовательских типов записей я хочу иметь возможность перечислять все записи по пользовательскому полю вместо даты их публикации (что для пользовательского типа записи, вероятно, не имеет значения). Я получил подсказку из комментариев в блоге о пользовательских типах сообщений, и автор сказал, что это возможно, и что он даже сделал это, чтобы вы могли щелкнуть по именам столбцов для пользовательской сортировки. Он упомянул о posts_orderby
функция, которую я отметил в своих собственных комментариях, но теперь я больше не могу найти запись в блоге. Есть какие-нибудь предложения? Я видел одно решение, которое использовало
add_action('wp', 'check_page');
И используемая функция check_page
add_filter
чтобы изменить запрос, но я почти уверен, что он будет работать только в файлах темы, а не в области администрирования.
3 answers
Как вы, вероятно, можете себе представить по отсутствию предоставленных ответов, решение не совсем тривиально. Что я сделал, так это создал несколько автономный пример, который предполагает пользовательский тип записи "movie
" и пользовательский ключ поля "Жанр".
Отказ от ответственности: это работает с WP3.0, но я не могу быть уверен, что это будет работать с более ранними версиями.
Вам в основном нужно зацепить два (2) крючка, чтобы это сработало, и еще два (2), чтобы сделать это очевидным и полезно.
Первым крючком является "restrict_manage_posts
", который позволяет вам выдавать HTML <select>
в области над списком сообщений, где фильтры " Массовые действия " и " Показывают даты ". Предоставленный код создаст функцию "Сортировать по:", как показано в этом фрагменте экрана:
( источник: mikeschinkel.com)
Код использует прямой SQL, потому что нет функции API WordPress для предоставления списка всех meta_keys для типов сообщений (звучит как будущий билет для меня...) В любом случае, вот код. Обратите внимание, что он берет тип записи из $_GET
и проверяет, является ли он как допустимым типом записи post_type_exists()
, так и типом записи movie
(эти две проверки излишни, но я сделал это, чтобы показать вам, как, если вы не хотите жестко кодировать тип записи.) Наконец, я использую параметр URL sortby
, поскольку он не конфликтует ни с чем другим в WordPress:
add_action('restrict_manage_posts','restrict_manage_movie_sort_by_genre');
function restrict_manage_movie_sort_by_genre() {
if (isset($_GET['post_type'])) {
$post_type = $_GET['post_type'];
if (post_type_exists($post_type) && $post_type=='movie') {
global $wpdb;
$sql=<<<SQL
SELECT pm.meta_key FROM {$wpdb->postmeta} pm
INNER JOIN {$wpdb->posts} p ON p.ID=pm.post_id
WHERE p.post_type='movie' AND pm.meta_key='Genre'
GROUP BY pm.meta_key
ORDER BY pm.meta_key
SQL;
$results = $wpdb->get_results($sql);
$html = array();
$html[] = "<select id=\"sortby\" name=\"sortby\">";
$html[] = "<option value=\"None\">No Sort</option>";
$this_sort = $_GET['sortby'];
foreach($results as $meta_key) {
$default = ($this_sort==$meta_key->meta_key ? ' selected="selected"' : '');
$value = esc_attr($meta_key->meta_key);
$html[] = "<option value=\"{$meta_key->meta_key}\"$default>{$value}</option>";
}
$html[] = "</select>";
echo "Sort by: " . implode("\n",$html);
}
}
}
Вторым необходимым шагом является чтобы использовать крючок parse_query
, который вызывается после того, как WordPress решит, какой запрос должен выполняться, но до того, как он выполнит запрос. Здесь мы устанавливаем значения orderby
и meta_key
в массиве query_var
запроса, которые задокументированы в Кодексе в параметре orderby
для query_posts()
. Мы проверяем, чтобы убедиться, что:
- Мы находимся в админ (
is_admin()
), - Мы находимся на странице, на которой перечислены записи в админке (
$pagenow=='edit.php'
), - Страница была вызвана с параметром URL
post_type
, равным кmovie
и - Страница также была вызвана с параметром URL
sortby
и что ей не было передано значение 'Нет'
Если все эти тесты пройдут, мы затем установим query_vars
(как задокументировано здесь ) в meta_value
и наше sortby
значение для 'Жанр':
add_filter( 'parse_query', 'sort_movie_by_meta_value' );
function sort_movie_by_meta_value($query) {
global $pagenow;
if (is_admin() && $pagenow=='edit.php' &&
isset($_GET['post_type']) && $_GET['post_type']=='movie' &&
isset($_GET['sortby']) && $_GET['sortby'] !='None') {
$query->query_vars['orderby'] = 'meta_value';
$query->query_vars['meta_key'] = $_GET['sortby'];
}
}
И это все, что вам нужно сделать; никаких "posts_order
" или "wp
" крючков не требуется! Конечно, вам действительно нужно сделать больше; вам нужно добавить несколько столбцов на свою страницу, в которых перечислены сообщения, чтобы вы действительно можете видеть значения, по которым он сортируется, иначе пользователи сильно запутаются. Поэтому добавьте крючок manage_{$post_type}_posts_columns
, в данном случае manage_movie_posts_columns
. Этому крючку передается массив столбцов по умолчанию, и для простоты я просто заменил его двумя стандартными столбцами; флажок (cb
) и имя сообщения (title
). (Вы можете проверить posts_columns
с помощью print_r()
, чтобы узнать, что еще доступно по умолчанию.)
Я решил добавить ", отсортированное по:", когда есть параметр URL sortby
и когда он нет None
:
add_action('manage_movie_posts_columns', 'manage_movie_posts_columns');
function manage_movie_posts_columns($posts_columns) {
$posts_columns = array(
'cb' => $posts_columns['cb'],
'title' => 'Movie Name',
);
if (isset($_GET['sortby']) && $_GET['sortby'] !='None')
$posts_columns['meta_value'] = 'Sorted By';
return $posts_columns;
}
Наконец, мы используем крючок manage_pages_custom_column
для фактического отображения значения, когда есть сообщение соответствующего типа и с вероятным избыточным тестом для is_admin()
и $pagenow=='edit.php'
. Когда есть параметр URL sortby
, мы извлекаем значение настраиваемого поля, которое сортируется, отображая его в нашем списке. Вот как это выглядит (помните, что это тестовые данные, поэтому никаких комментариев от галереи арахиса по классификациям фильмов! :):
( источник: mikeschinkel.com)
И вот код:
add_action('manage_pages_custom_column', 'manage_movie_pages_custom_column',10,2);
function manage_movie_pages_custom_column($column_name,$post_id) {
global $pagenow;
$post = get_post($post_id);
if ($post->post_type=='movie' && is_admin() && $pagenow=='edit.php') {
switch ($column_name) {
case 'meta_value':
if (isset($_GET['sortby']) && $_GET['sortby'] !='None') {
echo get_post_meta($post_id,$_GET['sortby'],true);
}
break;
}
}
}
Обратите внимание, что это только выбирает первый "Жанр" для movie
, т. Е. Первое мета_значение в случае нескольких значений для данного ключа. Но опять же, я не уверен, как бы это работало иначе!
И для тех, кто не знает, куда поместить этот код, вы можете поместить его в плагин или, что более вероятно, для новичка в файле functions.php
в ваша текущая тема.
Как это помогает.
По состоянию на WordPress 3.1 (Я использую бета-версию) столбцы теперь можно сортировать по их названиям.
В следующем посте подробно описывается, как их реализовать.
Вот простое решение:
/* --------Sortable Events on Dashboard - show start date, time, venue--------- */
/*-------------------------------------------------------------------------------
Custom Columns
-------------------------------------------------------------------------------*/
function my_*YOUR POST TYPE*_columns($columns)
{
$columns = array(
'cb' => '<input type="checkbox" />',
'title' => 'Title',
'your_custom_field' => 'Custom Field Name',
'date' => 'Date',
);
return $columns;
}
function my_custom_columns($column)
{
global $post;
if($column == 'your_custom_field')
{
if(get_post_meta($post->ID, 'your_custom_field', true);)
{
echo get_post_meta($post->ID, 'your_custom_field', true);
}
}
}
add_action("manage_posts_custom_column", "my_custom_columns");
add_filter("manage_edit-*YOUR POST TYPE*_columns", "my_events_columns");
/*-------------------------------------------------------------------------------
Sortable Columns
-------------------------------------------------------------------------------*/
function my_column_register_sortable( $columns )
{
$columns['your_custom_field'] = 'your_custom_field';
return $columns;
}
add_filter("manage_edit-*YOUR POST TYPE*_sortable_columns", "my_column_register_sortable" );
Просто замените ТИП ВАШЕГО СООБЩЕНИЯ и 'your_custom_ поле'