it-swarm.dev

So sortieren Sie den Administrationsbereich eines benutzerdefinierten WordPress-Beitragstyps nach einem benutzerdefinierten Feld

Wenn ich einen meiner benutzerdefinierten Beitragstypen bearbeite, möchte ich in der Lage sein, alle Einträge nach einem benutzerdefinierten Feld anstelle des Veröffentlichungsdatums aufzulisten (was für einen benutzerdefinierten Beitragstyp wahrscheinlich nicht relevant ist). Die Kommentare eines Blogposts zu benutzerdefinierten Post-Typen haben mir einen Hinweis gegeben, und der Autor sagte, dass dies möglich ist und dass er es sogar erstellt hat, damit Sie auf die Spaltennamen klicken können, um eine benutzerdefinierte Sortierung vorzunehmen. Er erwähnte die posts_orderby Funktion, die ich in meinen eigenen Kommentaren notiert habe, aber jetzt kann ich den Blog-Beitrag nicht mehr finden. Irgendwelche Vorschläge? Ich sah eine Lösung, die verwendet wurde

add_action('wp', 'check_page');

Und die Funktion check_page hat add_filter verwendet, um die Abfrage zu ändern, aber ich bin mir ziemlich sicher, dass sie nur in den Designdateien funktioniert, nicht im Administrationsbereich.

52
tooshel

Wie Sie sich aufgrund der fehlenden Antworten wahrscheinlich vorstellen können, ist die Lösung nicht gerade trivial. Ich habe ein eigenständiges Beispiel erstellt, das den benutzerdefinierten Beitragstyp "movie" und den benutzerdefinierten Feldschlüssel "Genre" voraussetzt.

Haftungsausschluss: Dies funktioniert mit WP3.0, aber ich kann nicht sicher sein, dass es mit früheren Versionen funktionieren wird.

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-<select> im Bereich über der Liste der Beiträge ausgeben können, in denen die Filter "Massenaktionen" und "Daten anzeigen" verwendet werden. Der bereitgestellte Code generiert die Funktion "Sortieren nach:", wie in diesem Bildschirmausschnitt dargestellt:

How to Create Sort By functionality for a Custom Post Type in the WordPress Admin
(Quelle: mikeschinkel.com )

Der Code verwendet direktes SQL, da es keine WordPress-API-Funktion gibt, die die Liste aller meta_keys für einen Beitragstyp bereitstellt (klingt wie ein Future trac Ticket für mich ...). Hier ist der Code. Beachten Sie, dass es den Post-Typ von $_GET abruft und überprüft, ob es sich sowohl um einen gültigen Post-Typ post_type_exists() als auch um einen movie-Post-Typ handelt um den Beitragstyp fest zu codieren.) Zuletzt verwende ich den URL-Parameter sortby, 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 Hooks parse_query, der aufgerufen wird, nachdem WordPress entschieden hat, welche Abfrage ausgeführt werden soll, bevor die Abfrage ausgeführt wird. Hier können wir die Werte von orderby und meta_key im Array query_var der Abfrage festlegen, die im Codex dokumentiert im Parameter orderby für query_posts() enthalten sind. Wir testen, um sicherzustellen, dass:

  1. Wir sind im Admin (is_admin()),
  2. Wir sind auf der Seite, die Beiträge im Admin ($pagenow=='edit.php') auflistet,
  3. Die Seite wurde mit einem post_type URL-Parameter aufgerufen, der movie entspricht
  4. Die Seite wurde auch mit einem URL-Parameter sortby aufgerufen und der Wert 'None' wurde nicht übergeben.

Wenn all diese Tests erfolgreich sind, setzen wir den query_vars (wie dokumentiert hier ) auf meta_value und unseren sortby -Wert 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" -Hooks 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 also einen manage_{$post_type}_posts_columns-Hook hinzu, in diesem Fall 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_columns mit einer print_r() überprüfen, um festzustellen, was standardmäßig noch verfügbar ist.)

Ich habe beschlossen, ein "Sorted By:" hinzuzufügen, wenn es einen URL-Parameter sortby gibt und wenn er nicht None ist:

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 Haken manage_pages_custom_column, 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 URL-Parameter sortby 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 Erdnuss-Galerie zu den Filmklassifizierungen! :):

Custom Columns added for a Custom Post Type in the WordPress Admin
(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 ein movie aufnimmt, d. H. Den ersten Meta_Wert im Fall von 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.php -Datei Ihres aktuellen Themas.

Wie das hilft.

66
MikeSchinkel

Ab WordPress 3.1 (ich benutze die Beta) können Spalten nun über ihre Titel sortiert werden.

Im folgenden Beitrag erfahren Sie, wie Sie diese implementieren.

http://scribu.net/wordpress/custom-sortable-columns.html

8
Leo Plaw