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:

(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 orderbyvà meta_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:
- Chúng tôi đang ở trong quản trị viên (
is_admin()),
- Chúng tôi đang ở trang liệt kê các bài đăng trong admin (
$pagenow=='edit.php'),
- Trang này đã được gọi với
post_typetham số URL bằng movievà
- 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_valuevà sortbygiá 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()và $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! :):

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