Come probabilmente puoi immaginare dalla mancanza di risposte fornite, la soluzione non è esattamente banale. Quello che ho fatto è creare un esempio un po 'autonomo che presuppone un tipo di post personalizzato di " movie
" e una chiave di campo personalizzata di " Genere ".
Disclaimer : funziona con WP3.0 ma non posso essere sicuro che funzionerà con le versioni precedenti.
Fondamentalmente devi agganciare due (2) ganci per farlo funzionare e altri due (2) per renderlo ovvio e utile.
Il primo hook è ' restrict_manage_posts
' che ti consente di emettere un HTML <select>
nell'area sopra l'elenco dei post in cui filtrano le " Azioni in blocco " e " Mostra date ". Il codice fornito genererà la funzionalità " Ordina per: " come mostrato in questo frammento di schermo:
(fonte: mikeschinkel.com )
Il codice utilizza l'SQL diretto perché non esiste una funzione API di WordPress per fornire l'elenco di tutti i meta_key per un tipo di post (mi sembra un futuro ticket trac ...) Comunque, ecco il codice. Nota che prende il tipo di post $_GET
e lo convalida per assicurarsi che sia sia un tipo di post valido post_type_exists()
sia un movie
tipo di post (quei due controlli sono eccessivi, ma l'ho fatto per mostrarti come se non vuoi hard- codificare il tipo di post.) Infine uso il sortby
parametro URL in quanto non è in conflitto con nient'altro in 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);
}
}
}
Il secondo passaggio richiesto è utilizzare l' parse_query
hook che viene chiamato dopo che WordPress ha deciso quale query deve essere eseguita ma prima che la esegua. Qui arriviamo a impostare i valori di orderby
e meta_key
nella query_var
matrice della query che sono documentati nel Codice nel orderby
parametro per query_posts()
. Testiamo per assicurarci che:
- Siamo nell'amministratore (
is_admin()
),
- Siamo nella pagina che elenca i post in admin (
$pagenow=='edit.php'
),
- La pagina è stata chiamata con un
post_type
parametro URL uguale a movie
, e
- La pagina è stata anche chiamata con un
sortby
parametro URL e non ha ricevuto il valore " Nessuno "
Se tutti questi test vengono superati, impostiamo query_vars
(come documentato qui ) su meta_value
e il nostro sortby
valore per " Genere ":
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 questo è tutto ciò che devi fare; nessun " posts_order
" o " wp
" gancio richiesto! Naturalmente in realtà devi fare di più; devi aggiungere alcune colonne alla tua pagina che elenchi i post in modo da poter effettivamente vedere i valori che sta ordinando altrimenti gli utenti rimarranno molto confusi. Quindi aggiungi un manage_{$post_type}_posts_columns
gancio, in questo caso manage_movie_posts_columns
. Questo hook viene superato l'array predefinito di colonne e per semplicità l'ho appena sostituito con due colonne standard; una casella di controllo ( cb
) e un nome di post ( title
). (Puoi controllare posts_columns
con a print_r()
per vedere cos'altro è disponibile per impostazione predefinita.)
Ho deciso di aggiungere un " Ordinato per: " per quando esiste un sortby
parametro URL e quando non lo è 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;
}
Infine usiamo l' manage_pages_custom_column
hook per visualizzare effettivamente il valore quando c'è un post del tipo di post appropriato e con il test probabilmente ridondante per is_admin()
e $pagenow=='edit.php'
. Quando esiste un sortby
parametro URL, estraiamo il valore del campo personalizzato che viene ordinato da un display nel nostro elenco. Ecco come appare (ricorda, questi sono i dati dei test, quindi nessun commento dalla galleria di arachidi sulle classificazioni dei film! :):
(fonte: mikeschinkel.com )
Ed ecco il codice:
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;
}
}
}
Nota che questo raccoglie solo il primo " Genere " per a movie
, cioè il primo meta_valore nel caso di più valori per una determinata chiave. Ma poi non sono sicuro di come funzionerebbe altrimenti!
E per chi non ha familiarità con la posizione in cui inserire questo codice, è possibile inserirlo in un plug-in o più probabilmente per il principiante nel functions.php
file nel tema corrente.
Come questo aiuta.