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ừ $_GET
và xác thực để đảm bảo rằng đó là loại bài đăng hợp lệ post_type_exists()
cũng như movie
loạ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 sortby
tham 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_query
hook đượ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 orderby
và meta_key
trong query_var
mảng truy vấn được ghi lại trong Codex trong orderby
tham 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_type
tham số URL bằng movie
và
- Trang này cũng đã được gọi với một
sortby
tham 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_value
và sortby
giá 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_columns
cá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_columns
vớ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ó sortby
tham 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_column
hook để 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 sortby
tham 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.php
tệp trong chủ đề hiện tại của bạn.
Làm thế nào điều này giúp.