ในขณะที่คุณสามารถจินตนาการได้โดยขาดคำตอบที่ให้ไว้วิธีการแก้ปัญหาไม่ได้เป็นเรื่องเล็กน้อย สิ่งที่ฉันทำคือสร้างตัวอย่างที่มีอยู่ในตัวเองซึ่งถือว่าประเภทโพสต์ที่กำหนดเองของ " movie
" และคีย์ฟิลด์ที่กำหนดเองของ " ประเภท "
ข้อจำกัดความรับผิดชอบ : สิ่งนี้ใช้ได้กับ WP3.0 แต่ฉันไม่แน่ใจว่ามันจะทำงานกับเวอร์ชันก่อนหน้านี้ได้หรือไม่
โดยทั่วไปคุณต้องขอสอง (2) hooks เพื่อให้มันทำงานและอีกสอง (2) เพื่อให้ชัดเจนและมีประโยชน์
เบ็ดแรกคือ ' restrict_manage_posts
' ซึ่งช่วยให้คุณปล่อย HTML <select>
ในพื้นที่ด้านบนรายการโพสต์ที่มีตัวกรอง "การกระทำเป็นกลุ่ม " และ " แสดงวันที่ " รหัสที่ให้มาจะสร้างฟังก์ชัน" เรียงตาม: " ตามที่เห็นในตัวอย่างหน้าจอนี้:
(ที่มา: mikeschinkel.com )
รหัสนี้ใช้ SQL โดยตรงเพราะไม่มีฟังก์ชั่น WordPress API เพื่อให้รายการของ meta_keys ทั้งหมดสำหรับประเภทโพสต์ (ฟังเหมือนตั๋วtracในอนาคตสำหรับฉัน ... ) อย่างไรก็ตามนี่คือรหัส โปรดทราบว่าประเภทคว้าโพสต์จาก$_GET
และตรวจสอบเพื่อให้แน่ใจว่ามันเป็นทั้งประเภทโพสต์ที่ถูกต้องpost_type_exists()
เช่นเดียวกับmovie
ประเภทโพสต์ (ตรวจสอบทั้งสองนั้นเป็น overkill แต่ฉันทำเพื่อแสดงให้คุณเห็นว่าถ้าคุณไม่ต้องการ โค้ดประเภทโพสต์) สุดท้ายฉันใช้sortby
พารามิเตอร์ URL เนื่องจากไม่ขัดแย้งกับสิ่งอื่นใน 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);
}
}
}
ขั้นตอนที่สองที่จำเป็นคือการใช้parse_query
เบ็ดที่เรียกว่าหลังจาก WordPress ตัดสินใจหนึ่งสิ่งที่แบบสอบถามควรจะทำงาน แต่ก่อนที่จะเรียกใช้แบบสอบถาม ที่นี่เราได้รับการตั้งค่าorderby
และmeta_key
ในแบบสอบถามของquery_var
อาเรย์ซึ่งได้รับการบันทึกไว้ใน Codexในพารามิเตอร์orderby
query_posts()
เราทดสอบเพื่อให้แน่ใจว่า:
- เราอยู่ในผู้ดูแลระบบ (
is_admin()
)
- เราอยู่ในหน้าที่แสดงรายการโพสต์ในผู้ดูแลระบบ (
$pagenow=='edit.php'
)
- หน้านี้ถูกเรียกใช้โดยมี
post_type
พารามิเตอร์ URL เท่ากับmovie
และ
- หน้านี้ถูกเรียกใช้พร้อมกับ
sortby
พารามิเตอร์ URL และไม่ได้ส่งค่าเป็น ' ไม่มี '
หากการทดสอบเหล่านั้นผ่านเราก็ตั้งค่าquery_vars
(ตามที่ระบุไว้ที่นี่ ) เป็นmeta_value
และsortby
ค่าของเราสำหรับ ' ประเภท ':
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'];
}
}
และนั่นคือทั้งหมดที่คุณต้องทำ ไม่จำเป็นต้องใช้ hooks " posts_order
" หรือ " wp
"! แน่นอนคุณต้องทำมากขึ้น คุณต้องเพิ่มบางคอลัมน์ในหน้าของคุณที่แสดงรายการการโพสต์เพื่อให้คุณสามารถดูค่าที่เรียงตามมิฉะนั้นผู้ใช้จะสับสนมาก ดังนั้นเพิ่มmanage_{$post_type}_posts_columns
ตะขอในกรณีmanage_movie_posts_columns
นี้ เบ็ดนี้ได้รับการผ่านอาร์เรย์เริ่มต้นของคอลัมน์และเพื่อความง่ายฉันเพิ่งแทนที่มันด้วยสองคอลัมน์มาตรฐาน ช่องทำเครื่องหมาย ( cb
) และชื่อโพสต์ ( title
) (คุณสามารถตรวจสอบposts_columns
ด้วย a print_r()
เพื่อดูว่ามีอะไรอื่นให้เลือกใช้ได้ตามค่าเริ่มต้น)
ฉันตัดสินใจเพิ่ม " เรียงลำดับตาม: " เมื่อมีsortby
พารามิเตอร์ URL และเมื่อไม่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;
}
ในที่สุดเราจะใช้manage_pages_custom_column
ตะขอที่จะแสดงจริงคุ้มค่าเมื่อมีการโพสต์ของประเภทโพสต์ที่เหมาะสมและมีการทดสอบอาจจะซ้ำซ้อนและis_admin()
$pagenow=='edit.php'
เมื่อมีsortby
พารามิเตอร์ URL เราจะแยกค่าฟิลด์ที่กำหนดเองที่จะเรียงลำดับตามการแสดงในรายการของเรา นี่คือสิ่งที่ดูเหมือน (โปรดจำไว้ว่านี่คือข้อมูลทดสอบดังนั้นจึงไม่มีความคิดเห็นจากแกลเลอรีถั่วลิสงในการจัดประเภทภาพยนตร์! :):
(ที่มา: mikeschinkel.com )
และนี่คือรหัส:
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;
}
}
}
โปรดทราบว่านี่จะเลือก " Genre " แรกสำหรับ a movie
เท่านั้นนั่นคือ meta_value แรกในกรณีที่มีค่าหลายค่าสำหรับคีย์ที่กำหนด แต่อีกครั้งฉันไม่แน่ใจว่ามันจะทำงานอย่างไร!
และสำหรับผู้ที่ไม่คุ้นเคยกับการวางรหัสนี้คุณสามารถวางไว้ในปลั๊กอินหรือเป็นไปได้มากขึ้นสำหรับมือใหม่ในfunctions.php
ไฟล์ในธีมปัจจุบันของคุณ
มันช่วยได้อย่างไร