Wie Sie sich aufgrund der fehlenden Antworten wahrscheinlich vorstellen können, ist die Lösung nicht gerade trivial. Was ich getan habe, ist ein etwas eigenständiges Beispiel zu erstellen, das einen benutzerdefinierten Beitragstyp " movie" und einen benutzerdefinierten Feldschlüssel " Genre " voraussetzt .
Haftungsausschluss : Dies funktioniert mit WP3.0, aber ich kann nicht sicher sein, ob es mit früheren Versionen funktioniert.
Grundsätzlich müssen Sie zwei (2) Haken einhaken, damit es funktioniert, und zwei (2) weitere, um es offensichtlich und nützlich zu machen.
Der erste Haken ist " restrict_manage_posts", mit dem Sie einen HTML-Code <select>im Bereich über der Liste der Beiträge ausgeben können, in denen die Filter " Massenaktionen " und " Datumsangaben anzeigen " verwendet werden. Der bereitgestellte Code generiert die Funktion " Sortieren nach: ", wie in diesem Bildschirmausschnitt dargestellt:

(Quelle: mikeschinkel.com )
Der Code verwendet direktes SQL, da es keine WordPress-API-Funktion gibt, mit der die Liste aller meta_keys für einen Beitragstyp bereitgestellt werden kann (das klingt für mich wie ein zukünftiges Trac- Ticket ...). Beachten Sie, dass der Post-Typ $_GETabgerufen und validiert wird, um sicherzustellen, dass er sowohl ein gültiger Post-Typ post_type_exists()als auch ein moviePost-Typ ist. Code den Beitragstyp.) Zuletzt verwende ich den sortbyURL-Parameter, da er mit nichts anderem in WordPress in Konflikt steht:
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);
}
}
}
Der zweite erforderliche Schritt ist die Verwendung des parse_queryHooks, der aufgerufen wird, nachdem WordPress entschieden hat, welche Abfrage ausgeführt werden soll, bevor die Abfrage ausgeführt wird. Hier setzen wir Werte von orderbyund meta_keyim query_varArray der Abfrage, die im Codex im orderbyParameter für dokumentiert sind query_posts(). Wir testen, um sicherzustellen, dass:
- Wir sind im admin (
is_admin()),
- Wir sind auf der Seite, die Beiträge in der admin (
$pagenow=='edit.php') auflistet ,
- Die Seite wurde mit einem
post_typeURL-Parameter aufgerufen, der gleich movieund ist
- Die Seite wurde auch mit einem
sortbyURL-Parameter aufgerufen und es wurde kein Wert von ' None ' übergeben.
Wenn all diese Tests erfolgreich sind, setzen wir das query_vars(wie hier dokumentiert ) auf meta_valueund unseren sortbyWert für ' 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'];
}
}
Und das ist alles, was Sie tun müssen. Keine " posts_order" oder " wp" Haken erforderlich! Natürlich müssen Sie tatsächlich mehr tun. Sie müssen einige Spalten auf Ihrer Seite hinzufügen, in denen die Beiträge aufgelistet sind, damit Sie tatsächlich die Werte sehen können, nach denen sortiert wird. Andernfalls werden die Benutzer sehr verwirrt. Fügen Sie manage_{$post_type}_posts_columnsin diesem Fall einen Haken hinzu manage_movie_posts_columns. Diesem Hook wird das Standard-Array von Spalten übergeben. Der Einfachheit halber habe ich es durch zwei Standardspalten ersetzt. ein Kontrollkästchen ( cb) und einen Beitragsnamen ( title). (Sie können posts_columnsmit einem prüfen print_r(), was standardmäßig noch verfügbar ist.)
Ich habe beschlossen, ein " Sortiert nach: " hinzuzufügen, wenn ein sortbyURL-Parameter vorhanden ist und wenn dies nicht der Fall ist 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;
}
Schließlich verwenden wir den manage_pages_custom_columnHaken, um den Wert tatsächlich anzuzeigen, wenn es einen Beitrag des entsprechenden Beitragstyps gibt und mit dem wahrscheinlich redundanten Test für is_admin()und $pagenow=='edit.php'. Wenn es einen sortbyURL-Parameter gibt, extrahieren wir den benutzerdefinierten Feldwert, der sortiert wird, indem er in unserer Liste angezeigt wird. Hier ist, wie es aussieht (denken Sie daran, dies sind Testdaten, also keine Kommentare aus der Erdnussgalerie zu den Filmklassifizierungen! :):

(Quelle: mikeschinkel.com )
Und hier ist der 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;
}
}
}
Beachten Sie, dass dies nur das erste " Genre " für a movieaufnimmt, dh den ersten meta_value bei mehreren Werten für einen bestimmten Schlüssel. Aber andererseits bin ich mir nicht sicher, wie es sonst funktionieren würde!
Und für diejenigen, die nicht wissen, wo dieser Code abgelegt werden soll, können Sie ihn in ein Plugin einfügen oder eher für den Neuling in der functions.phpDatei Ihres aktuellen Themas.
Wie das hilft.