Como você provavelmente pode imaginar pela falta de respostas fornecidas, a solução não é exatamente trivial. O que eu fiz foi criar um exemplo um pouco independente que pressupõe um tipo de postagem personalizado de " movie
" e uma chave de campo personalizada de " Gênero ".
Isenção de responsabilidade : isso funciona com o WP3.0, mas não tenho certeza se ele funcionará com versões anteriores.
Você basicamente precisa conectar dois (2) ganchos para fazê-lo funcionar e outros dois (2) para torná-lo óbvio e útil.
O primeiro gancho é ' restrict_manage_posts
', que permite emitir um HTML <select>
na área acima da lista de postagens em que os filtros " Ações em massa " e " Mostrar datas ". O código fornecido gerará a funcionalidade " Classificar por: ", como visto neste snippet da tela:
(fonte: mikeschinkel.com )
O código usa o SQL direto porque não há uma função da API do WordPress para fornecer a lista de todas as meta_keys para tipos de postagens (parece um ticket trac futuro para mim ...) De qualquer forma, aqui está o código. Observe que ele pega o tipo de postagem $_GET
e valida para garantir que seja um tipo de postagem válido post_type_exists()
e também um movie
tipo de postagem (essas duas verificações são um exagero, mas eu fiz isso para mostrar a você como se você não quiser codifique o tipo de postagem.) Por fim, uso o sortby
parâmetro URL, pois não entra em conflito com mais nada no 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);
}
}
}
A segunda etapa necessária é usar o parse_query
gancho chamado depois que o WordPress decidir um que consulta deve ser executada, mas antes de executá-la. Aqui, podemos definir valores de orderby
e meta_key
na query_var
matriz da consulta que estão documentados no Codex no orderby
parâmetro for query_posts()
. Testamos para garantir que:
- Estamos no admin (
is_admin()
),
- Estamos na página que lista as postagens no admin (
$pagenow=='edit.php'
),
- A página foi chamada com um
post_type
parâmetro de URL igual a movie
, e
- A página também foi chamada com um
sortby
parâmetro de URL e não recebeu um valor de ' Nenhum '
Se todos esses testes forem aprovados, definiremos o query_vars
(como documentado aqui ) como meta_value
e nosso sortby
valor para ' Gênero ':
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'];
}
}
E é tudo o que você precisa fazer; não são necessários ganchos " posts_order
" ou " wp
"! Claro que você realmente precisa fazer mais; você precisa adicionar algumas colunas em sua página que listam as postagens, para que você possa realmente ver os valores pelos quais está classificando, caso contrário os usuários ficarão confusos. Portanto, adicione um manage_{$post_type}_posts_columns
gancho, neste caso manage_movie_posts_columns
. Esse gancho é passado na matriz padrão de colunas e, por simplicidade, substituí-o por duas colunas padrão; uma caixa de seleção ( cb
) e um nome de postagem ( title
). (Você pode inspecionar posts_columns
com a print_r()
para ver o que mais está disponível por padrão.)
Decidi adicionar um " Ordenado por: " para quando houver um sortby
parâmetro de URL e quando não houver 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;
}
Finalmente, usamos o manage_pages_custom_column
gancho para realmente exibir o valor quando há uma postagem do tipo de postagem apropriada e com o teste provavelmente redundante para is_admin()
e $pagenow=='edit.php'
. Quando existe um sortby
parâmetro de URL, extraímos o valor do campo personalizado que está sendo classificado por um exibi-lo em nossa lista. Aqui está o que parece (lembre-se, são dados de teste, portanto, não há comentários da galeria de amendoins nas classificações de filmes! :):
(fonte: mikeschinkel.com )
E aqui está o código:
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;
}
}
}
Observe que isso seleciona apenas o primeiro " Gênero " para a movie
, ou seja, o primeiro meta_value no caso de vários valores para uma determinada chave. Mas, novamente, não tenho certeza de como isso funcionaria de outra maneira!
E para aqueles que não estão familiarizados com onde colocar esse código, você pode colocá-lo em um plug-in ou, mais provavelmente, para o iniciante no functions.php
arquivo em seu tema atual.
Como isso ajuda.