Come ordinare l'area di amministrazione di un tipo di post personalizzato di WordPress in base a un campo personalizzato


52

Quando modifico uno dei miei tipi di post personalizzati, voglio essere in grado di elencare tutte le voci in base a un campo personalizzato anziché alla data in cui sono pubblicate (che, per un tipo di post personalizzato probabilmente non è pertinente). Ho ottenuto un indizio dai commenti di un post sul blog sui tipi di post personalizzati e l'autore ha detto che era possibile e che ha persino fatto in modo che tu possa fare clic sui nomi delle colonne per un ordinamento personalizzato. Ha menzionato la posts_orderbyfunzione che ho notato nei miei commenti, ma ora posso trovare più il post sul blog. Eventuali suggerimenti? Ho visto una soluzione che ha usato

add_action('wp', 'check_page');

E la check_pagefunzione utilizzata add_filterper modificare la query, ma sono abbastanza sicuro che funzionerebbe solo nei file dei temi, non nell'area di amministrazione.


1
Ecco un'altra risposta utile, per ordinare i post per .... <br/> wordpress.stackexchange.com/questions/66455/…
T.Todua

Risposte:


66

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:

Come creare la funzionalità Ordina per per un tipo di post personalizzato nell'amministratore di WordPress
(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 $_GETe lo convalida per assicurarsi che sia sia un tipo di post valido post_type_exists()sia un movietipo 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 sortbyparametro 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_queryhook 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 orderbye meta_keynella query_varmatrice della query che sono documentati nel Codice nel orderbyparametro per query_posts(). Testiamo per assicurarci che:

  1. Siamo nell'amministratore ( is_admin()),
  2. Siamo nella pagina che elenca i post in admin ( $pagenow=='edit.php'),
  3. La pagina è stata chiamata con un post_typeparametro URL uguale a movie, e
  4. La pagina è stata anche chiamata con un sortbyparametro URL e non ha ricevuto il valore " Nessuno "

Se tutti questi test vengono superati, impostiamo query_vars(come documentato qui ) su meta_valuee il nostro sortbyvalore 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_columnsgancio, 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_columnscon a print_r()per vedere cos'altro è disponibile per impostazione predefinita.)

Ho deciso di aggiungere un " Ordinato per: " per quando esiste un sortbyparametro 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_columnhook 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 sortbyparametro 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! :):

Colonne personalizzate aggiunte per un tipo di post personalizzato nell'amministratore di WordPress
(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.phpfile nel tema corrente.

Come questo aiuta.


2
+1, solo per lo sforzo. Ma sarebbe ancora meglio se i cerchi fossero disegnati a mano :-)
Jan Fabry,

Hai idea di come rimuovere completamente il filtro MOSTRA TUTTE LE DATE in modo che vengano visualizzati solo i miei filtri personalizzati per un determinato tipo di post?
RailsTweeter,

@RailsTweeter Usa la tecnica che ho mostrato qui dove sono i due hook che racchiudono la generazione HTML 'months_dropdown_results'e 'restrict_manage_posts'. I voti PS sono sempre apprezzati. :)
MikeSchinkel,

@MikeSchinkel, ora che esiste un'API WP, aggiornerà in qualche modo il tuo codice?
Samjco,

@samjco Non sono sicuro. Purtroppo non ho il tempo di rivedere questo al momento.
MikeSchinkel,


-1

Ecco una soluzione semplice:

/* --------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" );

Basta sostituire il TUO POST TYPE e 'your_custom_field'

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.