Cách sắp xếp khu vực quản trị của loại bài đăng tùy chỉnh WordPress theo trường tùy chỉnh


52

Khi chỉnh sửa một trong các loại bài đăng tùy chỉnh của tôi, tôi muốn có thể liệt kê tất cả các mục theo trường tùy chỉnh thay vì ngày chúng được xuất bản (đối với loại bài đăng tùy chỉnh có thể không liên quan). Tôi đã nhận được sự dẫn dắt từ các bình luận của một bài đăng trên blog về các loại bài đăng tùy chỉnh và tác giả nói rằng điều đó là có thể và anh ấy thậm chí đã làm nó để bạn có thể nhấp vào tên cột để sắp xếp tùy chỉnh. Ông đã đề cập đến posts_orderbychức năng mà tôi ghi nhận trong các bình luận của riêng tôi nhưng bây giờ tôi có thể tìm thấy bài viết trên blog nữa. Bất kỳ đề xuất? Tôi thấy một giải pháp đã sử dụng

add_action('wp', 'check_page');

check_pagechức năng được sử dụng add_filterđể thay đổi truy vấn nhưng tôi khá chắc chắn rằng nó sẽ chỉ hoạt động trong các tệp chủ đề, không phải trong khu vực quản trị.


1
Ở đây một câu trả lời hữu ích, để sắp xếp các bài viết của .... <br/> wordpress.stackexchange.com/questions/66455/...
T.Todua

Câu trả lời:


66

Như bạn có thể tưởng tượng bằng cách thiếu câu trả lời được cung cấp, giải pháp không chính xác tầm thường. Những gì tôi đã làm là tạo một ví dụ có phần khép kín, giả sử loại bài đăng tùy chỉnh " movie" và khóa trường tùy chỉnh của " Thể loại ".

Disclaimer : điều này hoạt động với WP3.0 nhưng tôi không thể chắc chắn nó sẽ hoạt động với các phiên bản trước.

Về cơ bản, bạn cần móc hai (2) móc để làm cho nó hoạt động và hai (2) khác để làm cho nó rõ ràng và hữu ích.

Móc đầu tiên là ' restrict_manage_posts' cho phép bạn phát HTML <select>trong khu vực phía trên danh sách các bài đăng có bộ lọc " Hành động hàng loạt " và " Hiển thị ngày ". Mã được cung cấp sẽ tạo ra chức năng " Sắp xếp theo: " như được thấy trong đoạn mã màn hình này:

Cách tạo Sắp xếp theo chức năng cho Loại bài đăng tùy chỉnh trong Quản trị viên WordPress
(nguồn: mikechinkel.com )

Mã này sử dụng SQL trực tiếp vì không có chức năng API WordPress để cung cấp danh sách tất cả meta_key cho một loại bài đăng (nghe giống như một vé trac trong tương lai với tôi ...) Dù sao, đây là mã. Lưu ý rằng nó lấy loại bài đăng từ $_GETvà xác thực để đảm bảo rằng đó là loại bài đăng hợp lệ post_type_exists()cũng như movieloại bài đăng (hai kiểm tra đó là quá mức cần thiết nhưng tôi đã làm điều đó để cho bạn thấy nếu bạn không muốn làm khó mã loại bài đăng.) Cuối cùng tôi sử dụng sortbytham số URL vì nó không xung đột với bất kỳ điều gì khác trong 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);
        }
    }
}

Bước bắt buộc thứ hai là sử dụng parse_queryhook được gọi sau khi WordPress quyết định một truy vấn nào nên chạy nhưng trước khi nó chạy truy vấn. Ở đây chúng ta có thể đặt các giá trị của orderbymeta_keytrong query_varmảng truy vấn được ghi lại trong Codex trong orderbytham số cho query_posts(). Chúng tôi kiểm tra để đảm bảo rằng:

  1. Chúng tôi đang ở trong quản trị viên ( is_admin()),
  2. Chúng tôi đang ở trang liệt kê các bài đăng trong admin ( $pagenow=='edit.php'),
  3. Trang này đã được gọi với post_typetham số URL bằng movie
  4. Trang này cũng đã được gọi với một sortbytham số URL và nó không được thông qua giá trị ' Không '

Nếu tất cả các bài kiểm tra đó vượt qua, chúng tôi sẽ đặt query_vars(như được ghi lại ở đây ) meta_valuesortbygiá trị của chúng tôi cho ' Thể loại ':

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

Và đó là tất cả những gì bạn cần làm; không cần móc " posts_order" hoặc " wp"! Tất nhiên bạn thực sự cần phải làm nhiều hơn; bạn cần thêm một số cột trên trang liệt kê các bài đăng để bạn thực sự có thể thấy các giá trị mà nó đang sắp xếp bằng cách khác nếu không người dùng sẽ bị nhầm lẫn. Vì vậy, thêm một manage_{$post_type}_posts_columnscái móc, trong trường hợp này manage_movie_posts_columns. Móc này được truyền qua mảng cột mặc định và để đơn giản, tôi chỉ thay thế nó bằng hai cột tiêu chuẩn; một hộp kiểm ( cb) và tên bài đăng ( title). (Bạn có thể kiểm tra posts_columnsvới a print_r()để xem những gì khác có sẵn theo mặc định.)

Tôi đã quyết định thêm " Sắp xếp theo: " khi có sortbytham số URL và khi không có 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;
}

Cuối cùng, chúng tôi sử dụng manage_pages_custom_columnhook để thực sự hiển thị giá trị khi có một bài đăng thuộc loại bài đăng phù hợp và với bài kiểm tra có thể dư thừa cho is_admin()$pagenow=='edit.php'. Khi có một sortbytham số URL, chúng tôi trích xuất giá trị trường tùy chỉnh đang được sắp xếp bằng cách hiển thị nó trong danh sách của chúng tôi. Đây là giao diện của nó (hãy nhớ, đây là dữ liệu thử nghiệm nên không có nhận xét nào từ bộ sưu tập đậu phộng về phân loại phim! :):

Cột tùy chỉnh được thêm cho Loại bài đăng tùy chỉnh trong Quản trị viên WordPress
(nguồn: mikechinkel.com )

Và đây là mã:

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

Lưu ý rằng điều này chỉ chọn " Thể loại " đầu tiên cho a movie, tức là meta_value đầu tiên trong trường hợp có nhiều giá trị cho một khóa đã cho. Nhưng sau đó một lần nữa tôi không chắc nó sẽ hoạt động như thế nào!

Và đối với những người không quen thuộc với nơi đặt mã này, bạn có thể đặt nó vào một plugin hoặc nhiều khả năng cho người mới trong functions.phptệp trong chủ đề hiện tại của bạn.

Làm thế nào điều này giúp.


2
+1, chỉ vì nỗ lực. Nhưng sẽ tốt hơn nữa nếu các vòng tròn được vẽ bằng tay :-)
Jan Fabry

Bạn có biết cách loại bỏ hoàn toàn bộ lọc SHOW ALL DATE để chỉ các bộ lọc tùy chỉnh của tôi hiển thị cho một loại bài đăng nhất định không?
RailsTweeter

@RailsTweeter Sử dụng kỹ thuật tôi đã trình bày ở đây, nơi hai móc nối tạo khung HTML 'months_dropdown_results''restrict_manage_posts'. PS Upvotes luôn được đánh giá cao. :)
MikeSchinkel

@MikeSchinkel, bây giờ đã có API WP, điều này có cập nhật mã của bạn không?
samjco

@samjco Không chắc chắn. Thật không may, tôi không có thời gian để sửa đổi điều này vào lúc này.
MikeSchinkel


-1

Đây là một giải pháp đơn giản:

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

Chỉ cần thay thế LOẠI POST của bạn'your_custom_field'

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.