Comme vous pouvez probablement l'imaginer par le manque de réponses fournies, la solution n'est pas vraiment triviale. Ce que j’ai fait est de créer un exemple assez autonome qui suppose un type de publication personnalisé de " movie
" et une clé de champ personnalisée de " Genre ".
Avertissement : cela fonctionne avec WP3.0 mais je ne peux pas être sûr que cela fonctionnera avec les versions précédentes.
En gros, vous devez accrocher deux (2) crochets pour que cela fonctionne et deux autres (2) pour le rendre évident et utile.
Le premier point d'accroche est ' restrict_manage_posts
', ce qui vous permet d'émettre un code HTML <select>
dans la zone située au-dessus de la liste des publications où les filtres " Actions globales " et " Afficher les dates ". Le code fourni générera la fonctionnalité " Tri par: " comme indiqué dans cet extrait d'écran:

(source: mikeschinkel.com )
Le code utilise le SQL direct car il n’existe pas de fonction API WordPress pour fournir la liste de toutes les méta_keys pour un type de publication (cela ressemble à un futur ticket de trac pour moi ...). Quoi qu’il en soit, voici le code. Notez qu’il saisit le type de message $_GET
et le valide pour s’assurer qu’il s’agit à la fois d’un type de message valide post_type_exists()
et d’un movie
type de message (ces deux vérifications sont excessives, mais j’ai fait cela pour vous montrer comment, si vous ne voulez pas forcer.) code le type de post.) Enfin, j'utilise le sortby
paramètre URL car il n’est en conflit avec rien d’autre dans 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);
}
}
}
La deuxième étape requise consiste à utiliser le parse_query
hook appelé après que WordPress ait décidé quelle requête devrait être exécutée, mais avant de l'exécuter. Nous arrivons ici à définir les valeurs de orderby
et meta_key
dans le query_var
tableau de la requête qui sont documentées dans le Codex dans le orderby
paramètre for query_posts()
. Nous testons pour nous assurer que:
- Nous sommes dans l'admin (
is_admin()
),
- Nous sommes sur la page qui répertorie les messages dans le admin (
$pagenow=='edit.php'
),
- La page a été appelée avec un
post_type
paramètre d'URL égal à movie
, et
- La page a également été appelée avec un
sortby
paramètre d'URL et la valeur " Aucune " n'a pas été transmise .
Si tous ces tests réussissent, nous définissons le query_vars
(comme indiqué ici ) sur meta_value
et notre sortby
valeur pour ' Genre ':
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'];
}
}
Et c'est tout ce que vous devez faire. pas de crochets " posts_order
" ou " wp
" requis! Bien sûr, vous devez en faire plus. vous devez ajouter sur votre page des colonnes qui répertorient les publications pour que vous puissiez réellement voir les valeurs qu’elle trie, sans quoi les utilisateurs perdraient leur confusion. Alors ajoutez un manage_{$post_type}_posts_columns
crochet, dans ce cas manage_movie_posts_columns
. Ce hook reçoit le tableau de colonnes par défaut et, pour des raisons de simplicité, je viens de le remplacer par deux colonnes standard; une case à cocher ( cb
) et un nom de poste ( title
). (Vous pouvez inspecter posts_columns
avec a print_r()
pour voir ce qui est disponible par défaut.)
J'ai décidé d'ajouter un " Tri par: " pour quand il y a un sortby
paramètre d'URL et quand il ne l'est pas 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;
}
Enfin, nous utilisons le manage_pages_custom_column
crochet pour afficher la valeur s’il existe une publication du type de publication approprié et avec le test probablement redondant pour is_admin()
et $pagenow=='edit.php'
. Lorsqu'il existe un sortby
paramètre d'URL, nous extrayons la valeur du champ personnalisé en cours de tri en la affichant dans notre liste. Voici à quoi ça ressemble (rappelez-vous, ce sont des données de test, donc pas de commentaire de la galerie Peanut sur les classifications de films! :):

(source: mikeschinkel.com )
Et voici le code:
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;
}
}
}
Notez que cela ne prend que le premier " Genre " pour un movie
, c'est-à-dire la première méta_value dans le cas de valeurs multiples pour une clé donnée. Mais là encore, je ne suis pas sûr de savoir comment cela fonctionnerait autrement!
Et pour ceux qui ne savent pas où placer ce code, vous pouvez le mettre dans un plugin ou plus vraisemblablement pour le novice dans le functions.php
fichier de votre thème actuel.
Comment cela aide.