it-swarm-vi.tech

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

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. Anh ấy đã đề cập đến chức năng posts_orderby mà tôi đã ghi chú trong các bình luận của riêng mình nhưng bây giờ tôi có thể tìm thấy bài đăng 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');

Và hàm check_page đượ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ị.

52
tooshel

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".

Tuyên bố miễn trừ trách nhiệm: đ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> ở 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:

 How to Create Sort By functionality for a Custom Post Type in the WordPress Admin 
(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 có vẻ như là một tương lai trac vé cho tôi ...) Dù sao, đây là mã. Lưu ý rằng nó lấy loại bài đăng từ $_GET và xác thực để đảm bảo rằng đó là cả loại bài đăng hợp lệ post_type_exists() cũng như là loại bài đăng movie (hai kiểm tra này quá mức nhưng tôi đã làm điều đó để cho bạn thấy nếu bạn không muốn để mã hóa loại bài đăng.) Cuối cùng tôi sử dụng tham số URL sortby 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 hook parse_query đượ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 chạy truy vấn. Ở đây, chúng ta có thể đặt các giá trị của orderbymeta_key trong mảng query_var của truy vấn được ghi lại trong Codex trong tham số orderby 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 quản trị viên ($pagenow=='edit.php'),
  3. Trang đã được gọi với tham số URL post_type bằng movie
  4. Trang này cũng đã được gọi với tham số URL sortby và nó không được thông qua giá trị 'Không có'

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 ) thành meta_value và giá trị sortby 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 yêu cầu 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, hãy thêm một móc manage_{$post_type}_posts_columns, trong trường hợp này là 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_columns bằng một 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ó tham số URL sortby và khi đó không phải là 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 hook manage_pages_custom_column để 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ể là dự phòng cho is_admin()$pagenow=='edit.php'. Khi có tham số URL sortby, 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! :):

 Custom Columns added for a Custom Post Type in the WordPress Admin 
(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 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 mã đó vào một plugin hoặc nhiều khả năng cho người mới trong tệp functions.php trong chủ đề hiện tại của bạn.

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

66
MikeSchinkel

Kể từ cột WordPress 3.1 (tôi đang sử dụng bản beta) giờ đây có thể được sắp xếp thông qua các tiêu đề của chúng.

Các bài viết sau đây chi tiết cách thực hiện chúng.

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

8
Leo Plaw