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 $_GETe valida para garantir que seja um tipo de postagem válido post_type_exists()e também um movietipo 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 sortbyparâ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_querygancho chamado depois que o WordPress decidir um que consulta deve ser executada, mas antes de executá-la. Aqui, podemos definir valores de orderbye meta_keyna query_varmatriz da consulta que estão documentados no Codex no orderbyparâ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_typeparâmetro de URL igual a movie, e
- A página também foi chamada com um
sortbyparâ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_valuee nosso sortbyvalor 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_columnsgancho, 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_columnscom a print_r()para ver o que mais está disponível por padrão.)
Decidi adicionar um " Ordenado por: " para quando houver um sortbyparâ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_columngancho 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 sortbyparâ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.phparquivo em seu tema atual.
Como isso ajuda.