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

52

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 sei und dass er es sogar erstellt habe, damit Sie auf die Spaltennamen klicken können, um eine benutzerdefinierte Sortierung vorzunehmen. Er erwähnte die posts_orderbyFunktion, die ich in meinen eigenen Kommentaren vermerkte, 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 check_pageFunktion add_filterzum Ändern der Abfrage, aber ich bin mir ziemlich sicher, dass sie nur in den Designdateien funktioniert, nicht im Administrationsbereich.

tooshel
quelle
1
Hier eine weitere nützliche Antwort, um die Beiträge nach ... zu sortieren. <br/> wordpress.stackexchange.com/questions/66455/…
T.Todua

Antworten:

66

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:

So erstellen Sie eine Sortierfunktion für einen benutzerdefinierten Beitragstyp in WordPress Admin
(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:

  1. Wir sind im admin ( is_admin()),
  2. Wir sind auf der Seite, die Beiträge in der admin ( $pagenow=='edit.php') auflistet ,
  3. Die Seite wurde mit einem post_typeURL-Parameter aufgerufen, der gleich movieund ist
  4. 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! :):

Benutzerdefinierte Spalten für einen benutzerdefinierten Beitragstyp in WordPress Admin hinzugefügt
(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.

MikeSchinkel
quelle
2
+1, nur für die Mühe. Aber es wäre noch besser, wenn die Kreise von Hand gezeichnet wären :-)
Jan Fabry
Hast du eine Idee, wie du den Filter ALLE DATEN ANZEIGEN vollständig entfernen kannst, sodass nur meine benutzerdefinierten Filter für einen bestimmten Beitragstyp angezeigt werden?
RailsTweeter
@RailsTweeter Wende die hier gezeigte Technik an, bei der die beiden Haken, die die HTML-Generierung einschließen, 'months_dropdown_results'und sind 'restrict_manage_posts'. PS Upvotes sind immer willkommen. :)
MikeSchinkel
@MikeSchinkel, jetzt, da es eine WP-API gibt, wird dies Ihren Code etwas aktualisieren?
Samjco
@samjco Nicht sicher. Leider habe ich im Moment keine Zeit, dies zu überarbeiten.
MikeSchinkel
-1

Hier ist eine einfache Lösung:

/* --------Sortable Events on Dashboard - show start date, time, venue--------- */

/*-------------------------------------------------------------------------------
    Custom Columns
-------------------------------------------------------------------------------*/

function my_*YOUR POST TYPE*_columns($columns)
{
    $columns = array(
        'cb'        => '<input type="checkbox" />',
        'title'     => 'Title',
        'your_custom_field'     => 'Custom Field Name',          
        'date'      =>  'Date',
    );
    return $columns;
}

function my_custom_columns($column)
{
    global $post;
    if($column == 'your_custom_field')
    {
        if(get_post_meta($post->ID, 'your_custom_field', true);)
        {
            echo get_post_meta($post->ID, 'your_custom_field', true);
        }
    }

}

add_action("manage_posts_custom_column", "my_custom_columns");
add_filter("manage_edit-*YOUR POST TYPE*_columns", "my_events_columns");

/*-------------------------------------------------------------------------------
    Sortable Columns
-------------------------------------------------------------------------------*/

function my_column_register_sortable( $columns )
{
    $columns['your_custom_field'] = 'your_custom_field';
    return $columns;
}

add_filter("manage_edit-*YOUR POST TYPE*_sortable_columns", "my_column_register_sortable" );

Ersetzen Sie einfach IHREN POST-TYP und "your_custom_field"

jake
quelle