ปัญหา
ตามค่าเริ่มต้นในบริบทใดก็ตาม WordPress ใช้เคียวรีหลักเพื่อกำหนดเลขหน้า วัตถุแบบสอบถามหลักจะถูกเก็บไว้ใน$wp_query
ส่วนกลางซึ่งยังใช้ในการส่งออกห่วงแบบสอบถามหลัก:
if ( have_posts() ) : while ( have_posts() ) : the_post();
เมื่อคุณใช้แบบสอบถามที่กำหนดเองคุณสร้างวัตถุแบบสอบถามแยกต่างหากทั้งหมด:
$custom_query = new WP_Query( $custom_query_args );
และแบบสอบถามนั้นถูกส่งออกผ่านการวนซ้ำที่แยกจากกันโดยสิ้นเชิง:
if ( $custom_query->have_posts() ) :
while ( $custom_query->have_posts() ) :
$custom_query->the_post();
แต่แท็กเลขแม่แบบรวมทั้งprevious_posts_link()
, next_posts_link()
, posts_nav_link()
และpaginate_links()
ฐานการส่งออกของพวกเขาในวัตถุแบบสอบถามหลัก$wp_query
, แบบสอบถามหลักนั้นอาจหรือไม่อาจแบ่งหน้า หากบริบทปัจจุบันเป็นเทมเพลตของหน้าเว็บที่กำหนดเองตัวอย่างเช่น$wp_query
วัตถุหลักจะมีเพียงโพสต์เดียวซึ่งเป็นรหัสของหน้าซึ่งมีการกำหนดเทมเพลตหน้าที่กำหนดเอง
หากบริบทปัจจุบันเป็นดัชนีที่เก็บถาวรของการเรียงลำดับบางอย่างหลัก$wp_query
อาจประกอบด้วยโพสต์มากพอที่จะทำให้เกิดการแบ่งหน้าซึ่งนำไปสู่ส่วนต่อไปของปัญหา: สำหรับ$wp_query
วัตถุหลักWordPress จะส่งpaged
พารามิเตอร์ไปยังแบบสอบถามตามpaged
ตัวแปรแบบสอบถาม URL เมื่อดึงแบบสอบถามแล้วpaged
พารามิเตอร์นั้นจะถูกใช้เพื่อกำหนดชุดของโพสต์ที่ให้เลขหน้าเพื่อส่งคืน หากมีการเชื่อมโยงการแบ่งหน้าแสดงการคลิกและหน้าถัดไปโหลดแบบสอบถามแบบกำหนดเองของคุณจะไม่มีทางใดที่จะรู้ว่าเลขที่มีการเปลี่ยนแปลง
การแก้ไขปัญหา
ผ่านพารามิเตอร์ Paged ที่ถูกต้องไปยัง Custom Query
สมมติว่าแบบสอบถามแบบกำหนดเองใช้อาร์เรย์ args:
$custom_query_args = array(
// Custom query parameters go here
);
คุณจะต้องส่งpaged
พารามิเตอร์ที่ถูกต้องไปยังอาร์เรย์ คุณสามารถทำได้โดยดึงตัวแปรคิวรี่ URL ที่ใช้เพื่อกำหนดหน้าปัจจุบันผ่านget_query_var()
:
get_query_var( 'paged' );
จากนั้นคุณสามารถผนวกพารามิเตอร์นั้นไปยังคิวรีแบบกำหนดเองของคุณทำอาร์เรย์อาร์เรย์
$custom_query_args['paged'] = get_query_var( 'paged' )
? get_query_var( 'paged' )
: 1;
หมายเหตุ:หากหน้าของคุณเป็นแบบหน้าคงที่ให้ใช้page
แทนpaged
หน้าแบบคงที่ใช้page
และไม่paged
ใช้ นี่คือสิ่งที่คุณควรมีสำหรับหน้าคงที่
$custom_query_args['paged'] = get_query_var( 'page' )
? get_query_var( 'page' )
: 1;
ตอนนี้เมื่อดึงเคียวรีที่กำหนดเองแล้วจะส่งคืนชุด paginated ที่ถูกต้องของโพสต์
การใช้ Custom Query Object สำหรับฟังก์ชันการแบ่งหน้า
เพื่อให้ฟังก์ชั่นการให้เลขหน้าให้ผลผลิตที่ถูกต้อง - เช่นการเชื่อมโยงก่อนหน้า / ถัดไป / หน้าเทียบกับแบบสอบถามที่กำหนดเอง - WordPress จะต้องถูกบังคับให้รับรู้แบบสอบถามที่กำหนดเอง สิ่งนี้ต้องใช้ "แฮ็ค": แทนที่$wp_query
วัตถุหลักด้วยวัตถุแบบสอบถามที่กำหนดเอง$custom_query
:
แฮ็ควัตถุเคียวรีหลัก
- สำรองข้อมูลวัตถุแบบสอบถามหลัก:
$temp_query = $wp_query
- ไม่มีวัตถุแบบสอบถามหลัก:
$wp_query = NULL;
สลับเคียวรีที่กำหนดเองเป็นวัตถุคิวรีหลัก: $wp_query = $custom_query;
$temp_query = $wp_query;
$wp_query = NULL;
$wp_query = $custom_query;
"แฮ็ค" นี้จะต้องทำก่อนที่จะเรียกฟังก์ชั่นเลขหน้า
รีเซ็ตวัตถุแบบสอบถามหลัก
เมื่อฟังก์ชั่นการแบ่งหน้าได้รับการส่งออกตั้งค่าวัตถุแบบสอบถามหลัก:
$wp_query = NULL;
$wp_query = $temp_query;
แก้ไขฟังก์ชันการแบ่งหน้า
previous_posts_link()
ฟังก์ชั่นจะทำงานได้ตามปกติโดยไม่คำนึงถึงการแบ่งหน้า page - 1
มันเป็นเพียงการกำหนดหน้าปัจจุบันแล้วเอาท์พุทสำหรับการเชื่อมโยง อย่างไรก็ตามจำเป็นต้องมีการแก้ไขสำหรับnext_posts_link()
การส่งออกอย่างถูกต้อง นี่เป็นเพราะnext_posts_link()
ใช้max_num_pages
พารามิเตอร์:
<?php next_posts_link( $label , $max_pages ); ?>
เช่นเดียวกับพารามิเตอร์การสืบค้นอื่น ๆ โดยค่าเริ่มต้นฟังก์ชั่นจะใช้max_num_pages
สำหรับ$wp_query
วัตถุหลัก เพื่อบังคับnext_posts_link()
ให้บัญชีสำหรับ$custom_query
วัตถุคุณจะต้องผ่านmax_num_pages
ไปยังฟังก์ชั่น คุณสามารถดึงค่านี้จาก$custom_query
วัตถุ$custom_query->max_num_pages
:
<?php next_posts_link( 'Older Posts' , $custom_query->max_num_pages ); ?>
วางมันทั้งหมดเข้าด้วยกัน
ต่อไปนี้เป็นโครงสร้างพื้นฐานของลูปแบบสอบถามที่กำหนดเองที่มีฟังก์ชั่นการแบ่งหน้าการทำงานอย่างถูกต้อง:
// Define custom query parameters
$custom_query_args = array( /* Parameters go here */ );
// Get current page and append to custom query parameters array
$custom_query_args['paged'] = get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1;
// Instantiate custom query
$custom_query = new WP_Query( $custom_query_args );
// Pagination fix
$temp_query = $wp_query;
$wp_query = NULL;
$wp_query = $custom_query;
// Output custom query loop
if ( $custom_query->have_posts() ) :
while ( $custom_query->have_posts() ) :
$custom_query->the_post();
// Loop output goes here
endwhile;
endif;
// Reset postdata
wp_reset_postdata();
// Custom query loop pagination
previous_posts_link( 'Older Posts' );
next_posts_link( 'Newer Posts', $custom_query->max_num_pages );
// Reset main query object
$wp_query = NULL;
$wp_query = $temp_query;
ภาคผนวก: เกี่ยวกับquery_posts()
อะไร
query_posts()
สำหรับลูปรอง
หากคุณกำลังใช้query_posts()
การส่งออกห่วงที่กำหนดเองแทนแล้ว instantiating วัตถุที่แยกต่างหากสำหรับแบบสอบถามแบบกำหนดเองผ่านWP_Query()
แล้วคุณ_doing_it_wrong()
และจะทำงานเป็นปัญหาหลาย (ไม่น้อยที่จะเป็นประเด็นที่เลขหน้า) ขั้นตอนแรกในการแก้ไขปัญหาเหล่านั้นคือการแปลงการใช้ที่ไม่เหมาะสมquery_posts()
ไปเป็นการWP_Query()
โทรที่เหมาะสม
การใช้query_posts()
เพื่อปรับเปลี่ยนลูปหลัก
ถ้าคุณเพียงต้องการที่จะปรับเปลี่ยนพารามิเตอร์สำหรับแบบสอบถามวงหลัก - เช่นการเปลี่ยนโพสต์ต่อหนึ่งหน้าหรือไม่รวมหมวดหมู่ - query_posts()
คุณอาจถูกล่อลวงไปใช้ แต่คุณก็ยังไม่ควร เมื่อคุณใช้query_posts()
คุณบังคับให้ WordPress เปลี่ยนวัตถุแบบสอบถามหลัก (WordPress สร้างคำถามที่สองจริง ๆ แล้วเขียนทับ$wp_query
) ปัญหาคือว่ามันจะแทนที่สิ่งนี้ช้าเกินไปในกระบวนการอัปเดตการแบ่งหน้า
วิธีการแก้ปัญหาคือการกรองแบบสอบถามหลักก่อนโพสต์จะถูกดึงผ่านpre_get_posts
เบ็ด
แทนที่จะเพิ่มสิ่งนี้ลงในไฟล์เทมเพลตหมวดหมู่ ( category.php
):
query_posts( array(
'posts_per_page' => 5
) );
เพิ่มรายการต่อไปนี้ในfunctions.php
:
function wpse120407_pre_get_posts( $query ) {
// Test for category archive index
// and ensure that the query is the main query
// and not a secondary query (such as a nav menu
// or recent posts widget output, etc.
if ( is_category() && $query->is_main_query() ) {
// Modify posts per page
$query->set( 'posts_per_page', 5 );
}
}
add_action( 'pre_get_posts', 'wpse120407_pre_get_posts' );
แทนที่จะเพิ่มสิ่งนี้ลงในไฟล์เทมเพลตดัชนีบล็อก ( home.php
):
query_posts( array(
'cat' => '-5'
) );
เพิ่มรายการต่อไปนี้ในfunctions.php
:
function wpse120407_pre_get_posts( $query ) {
// Test for main blog posts index
// and ensure that the query is the main query
// and not a secondary query (such as a nav menu
// or recent posts widget output, etc.
if ( is_home() && $query->is_main_query() ) {
// Exclude category ID 5
$query->set( 'category__not_in', array( 5 ) );
}
}
add_action( 'pre_get_posts', 'wpse120407_pre_get_posts' );
ด้วยวิธีนี้ WordPress จะใช้$wp_query
วัตถุที่ถูกแก้ไขแล้วเมื่อกำหนดเลขหน้าโดยไม่จำเป็นต้องแก้ไขเทมเพลต
เมื่อใดจึงจะใช้ฟังก์ชั่น
งานวิจัยนี้คำถามและคำตอบและคำถามนี้และคำตอบจะเข้าใจวิธีการและเมื่อใช้WP_Query
, และpre_get_posts
query_posts()