Jak posortować obszar administracyjny niestandardowego typu postu WordPress według niestandardowego pola

52

Podczas edytowania jednego z moich niestandardowych typów postów chcę móc wyświetlić listę wszystkich wpisów według niestandardowego pola zamiast daty ich opublikowania (co w przypadku niestandardowego typu postu prawdopodobnie nie ma znaczenia). Dostałem wskazówki od komentarzy na blogu na temat niestandardowych typów postów, a autor powiedział, że jest to możliwe, a nawet to zrobił, abyś mógł kliknąć nazwy kolumn dla niestandardowego sortowania. Wspomniał o posts_orderbyfunkcji, którą zauważyłem we własnych komentarzach, ale teraz mogę już znaleźć post na blogu. Jakieś sugestie? Widziałem jedno zastosowane rozwiązanie

add_action('wp', 'check_page');

I check_pagefunkcja użyta add_filterdo zmiany zapytania, ale jestem prawie pewien, że zadziała tylko w plikach motywów, a nie w obszarze administracyjnym.

Tooshel
źródło
1
Oto kolejna przydatna odpowiedź, aby posortować posty według ... <br/> wordpress.stackexchange.com/questions/66455/…
T.Todua

Odpowiedzi:

66

Jak zapewne można sobie wyobrazić z powodu braku odpowiedzi, rozwiązanie nie jest trywialne. To, co zrobiłem, to stworzenie dość samodzielnego przykładu, który zakłada niestandardowy typ posta „ movie” i niestandardowy klucz pola „ Gatunek ”.

Oświadczenie : działa z WP3.0, ale nie mogę być pewien, że będzie działać z wcześniejszymi wersjami.

Zasadniczo musisz zaczepić dwa (2) haki, aby działało, a kolejne dwa (2), aby uczynić je oczywistym i użytecznym.

Pierwszy haczyk to „ restrict_manage_posts”, który pozwala emitować kod HTML <select>w obszarze nad listą postów, w których filtry „ Akcje zbiorcze ” i „ Pokaż daty ”. Podany kod wygeneruje funkcję „ Sortuj według: ”, jak widać na tym fragmencie ekranu:

Jak utworzyć funkcję Sortuj według dla niestandardowego typu postu w Administratorze WordPress
(źródło: mikeschinkel.com )

Kod używa bezpośredniego SQL, ponieważ nie ma funkcji API WordPress, która zapewnia listę wszystkich meta_keys dla typów postów (brzmi jak przyszły bilet trac dla mnie ...) W każdym razie, oto kod. Pamiętaj, że pobiera typ postu $_GETi sprawdza, czy jest to zarówno prawidłowy typ postu, post_type_exists()jak i movietyp postu (te dwie kontrole są przesadzone, ale zrobiłem to, aby pokazać ci, jak jeśli nie chcesz, aby- kod typu postu.) Wreszcie używam sortbyparametru URL, ponieważ nie powoduje konfliktu z niczym innym w 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);
        }
    }
}

Drugim wymaganym krokiem jest użycie parse_queryhaka, który jest wywoływany po tym, jak WordPress decyduje, które zapytanie powinno zostać uruchomione, ale przed uruchomieniem zapytania. Tutaj możemy ustawić wartości orderbyi meta_keyw query_vartablicy zapytania, które są udokumentowane w Kodeksie w orderbyparametrze dla query_posts(). Testujemy, aby upewnić się, że:

  1. Jesteśmy w admin ( is_admin()),
  2. Jesteśmy na stronie z listą postów w admin ( $pagenow=='edit.php'),
  3. Strona została wywołana z post_typeparametrem URL równym movie, i
  4. Strona została również wywołana z sortbyparametrem URL i że nie przekazano jej wartości „ Brak

Jeśli wszystkie te testy zakończą się pomyślnie, ustawiamy query_vars(zgodnie z opisem tutaj ) meta_valuei naszą sortbywartość dla „ Gatunek ”:

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'];
    }
}

I to wszystko, co musisz zrobić; nie są wymagane haki „ posts_order” ani „ wp”! Oczywiście musisz zrobić więcej; musisz dodać na swojej stronie kilka kolumn, które zawierają listę postów, abyś mógł zobaczyć wartości, według których się sortuje, w przeciwnym razie użytkownicy bardzo się pomylą. Więc dodaj manage_{$post_type}_posts_columnshaczyk w tym przypadku manage_movie_posts_columns. Ten hak dostaje domyślną tablicę kolumn i dla uproszczenia właśnie zastąpiłem ją dwiema standardowymi kolumnami; pole wyboru ( cb) i nazwa posta ( title). (Możesz sprawdzić za posts_columnspomocą a, print_r()aby zobaczyć, co jeszcze jest dostępne domyślnie.)

Zdecydowałem się dodać „ Posortowane według: ”, gdy istnieje sortbyparametr adresu URL, a gdy nie jest to 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;
}

Na koniec używamy manage_pages_custom_columnhaka do wyświetlania wartości, gdy jest słupek odpowiedniego typu słupka i prawdopodobnie z redundantnym testem dla is_admin()i $pagenow=='edit.php'. Gdy istnieje sortbyparametr adresu URL, wyodrębniamy niestandardową wartość pola, która jest sortowana, wyświetlając ją na naszej liście. Oto jak to wygląda (pamiętaj, że to dane testowe, więc nie ma komentarzy z galerii orzechów w klasyfikacjach filmowych! :):

Dodano niestandardowe kolumny dla niestandardowego typu postu w Administratorze WordPress
(źródło: mikeschinkel.com )

A oto kod:

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;
        }
    }
}

Zauważ, że to wybiera tylko pierwszy „ gatunek ” dla a movie, tj. Pierwszą meta_wartość w przypadku wielu wartości dla danego klucza. Ale z drugiej strony nie jestem pewien, jak inaczej by to działało!

A dla tych, którzy nie wiedzą, gdzie umieścić ten kod, możesz umieścić go we wtyczce lub bardziej prawdopodobne dla początkującego w functions.phppliku w bieżącym motywie.

Jak to pomaga.

MikeSchinkel
źródło
2
+1, tylko za wysiłek. Ale byłoby jeszcze lepiej, gdyby koła były rysowane ręcznie :-)
Jan Fabry
Masz pomysł, jak całkowicie usunąć filtr POKAŻ WSZYSTKIE DANE, aby wyświetlały się tylko moje filtry niestandardowe dla danego typu postu?
RailsTweeter
@RailsTweeter pomocą techniki pokazałem tutaj, gdzie dwa haczyki że wspornik generowanie HTML są 'months_dropdown_results'i 'restrict_manage_posts'. PS Upvotes są zawsze mile widziane. :)
MikeSchinkel
@MikeSchinkel, teraz, gdy istnieje WP API, czy to trochę zaktualizuje twój kod?
samjco
@samjco Nie jestem pewien. Niestety nie mam teraz czasu, aby to zmienić.
MikeSchinkel
-1

Oto proste rozwiązanie:

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

Po prostu zastąp swój TYP POCZTY i „twoje_standardowe_pole”

jake
źródło