Как вы можете, вероятно, догадаться по отсутствию ответов, решение не совсем тривиально. Что я сделал, так это создал несколько автономный пример, который предполагает собственный тип записи " movie
" и ключ настраиваемого поля " Жанр ".
Отказ от ответственности : это работает с WP3.0, но я не уверен, что он будет работать с более ранними версиями.
В основном вам нужно зацепить два (2) хука, чтобы он работал, и еще два (2), чтобы сделать его очевидным и полезным.
Первый хук - это ' restrict_manage_posts
', который позволяет вам генерировать HTML <select>
в области над списком постов, где фильтры " Массовые действия " и " Показывать даты ". Предоставленный код будет генерировать функциональность « Сортировать по: », как показано в следующем фрагменте экрана:
(источник: mikeschinkel.com )
Код использует прямой SQL , потому что это не функция WordPress API , чтобы обеспечить список всех meta_keys на пост типов (звучит как будущий Trac билет мне ...) Во всяком случае, вот код. Обратите внимание, что он извлекает тип записи из $_GET
и проверяет, чтобы убедиться, что это и правильный тип записи, post_type_exists()
и movie
тип записи (эти две проверки являются избыточными, но я сделал это, чтобы показать вам, как, если вы не хотите закодируйте тип сообщения.) Наконец, я использую sortby
параметр URL, поскольку он не конфликтует ни с чем в 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'
),
- Страница была вызвана с
post_type
параметром URL, равным movie
, и
- Страница также была вызвана с
sortby
параметром URL, и ей не было присвоено значение « Нет ».
Если все эти тесты пройдены, мы устанавливаем 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()
чтобы увидеть, что еще доступно по умолчанию.)
Я решил добавить « Sorted By: », когда есть sortby
параметр URL, а когда его нет 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'
. Когда есть sortby
параметр URL, мы извлекаем значение настраиваемого поля, которое сортируется, отображая его в нашем списке. Вот как это выглядит (помните, это тестовые данные, поэтому нет комментариев из галереи арахиса о классификации фильмов! :):
(источник: 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;
}
}
}
Обратите внимание, что это выбирает только первый « Жанр » для a movie
, то есть первое meta_value в случае нескольких значений для данного ключа. Но опять же, я не уверен, как это будет работать в противном случае!
А для тех, кто не знает, где разместить этот код, вы можете поместить его в плагин или, скорее всего, для новичка в functions.php
файле в вашей текущей теме.
Как это помогает