समस्या
डिफ़ॉल्ट रूप से, किसी भी संदर्भ में, वर्डप्रेस पेजिनेशन निर्धारित करने के लिए मुख्य क्वेरी का उपयोग करता है। मुख्य क्वेरी ऑब्जेक्ट को $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
वस्तु के लिए, वर्डप्रेस paged
क्वेरी के आधार पर एक पैरामीटर पारित करेगा । paged
URL क्वेरी चर। जब क्वेरी प्राप्त होती है, तो उस paged
पैरामीटर का उपयोग यह निर्धारित करने के लिए किया जाएगा कि कौन से पृष्ठ पर वापस जाने के लिए पृष्ठांकित पदों का सेट है। यदि एक प्रदर्शित पृष्ठांकन लिंक पर क्लिक किया जाता है, और अगले पृष्ठ को लोड किया जाता है, तो आपके कस्टम क्वेरी के पास यह जानने का कोई तरीका नहीं होगा कि पृष्ठांकन बदल गया है ।
समाधान
कस्टम क्वेरी में सही पृष्ठांकित पासिंग
यह मानते हुए कि कस्टम क्वेरी एक आर्ग्स सरणी का उपयोग करती है:
$custom_query_args = array(
// Custom query parameters go here
);
आपको paged
सरणी के लिए सही पैरामीटर पास करना होगा । आप वर्तमान पृष्ठ को निर्धारित करने के लिए उपयोग किए गए URL क्वेरी चर को प्राप्त करके ऐसा कर सकते हैं get_query_var()
:
get_query_var( 'paged' );
फिर आप उस पैरामीटर को अपनी कस्टम क्वेरी args सरणी में जोड़ सकते हैं:
$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;
अब, जब कस्टम क्वेरी प्राप्त होती है, तो पृष्ठांकित पदों का सही सेट वापस आ जाएगा।
पेजेशन फंक्शंस के लिए कस्टम क्वेरी ऑब्जेक्ट का उपयोग करना
पृष्ठांकन फ़ंक्शन के लिए सही आउटपुट प्राप्त करने के लिए - यानी कस्टम क्वेरी के सापेक्ष पिछले / अगले / पृष्ठ लिंक - वर्डप्रेस को कस्टम क्वेरी को पहचानने के लिए मजबूर करने की आवश्यकता है। इसके लिए "हैक" की आवश्यकता है: $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()
एक कस्टम लूप का उत्पादन करने के लिए उपयोग कर रहे हैं , बल्कि तब के माध्यम से कस्टम क्वेरी के लिए एक अलग ऑब्जेक्ट को इंस्टेंट WP_Query()
कर रहे हैं _doing_it_wrong()
, तो आप कर रहे हैं , और कई समस्याओं में भाग लेंगे ( जिनमें से कम से कम अंकन मुद्दे होंगे)। उन मुद्दों को हल करने के लिए पहला कदम query_posts()
उचित WP_Query()
कॉल के अनुचित उपयोग को परिवर्तित करना होगा ।
query_posts()
मुख्य लूप को संशोधित करने के लिए उपयोग करना
यदि आप केवल मुख्य लूप क्वेरी के लिए मापदंडों को संशोधित करना चाहते हैं - जैसे कि प्रति पृष्ठ पदों को बदलना, या एक श्रेणी को छोड़कर - आपको उपयोग करने के लिए परीक्षा हो सकती है query_posts()
। लेकिन आप अभी भी नहीं करना चाहिए। जब आप उपयोग करते हैं query_posts()
, तो आप वर्डप्रेस को मुख्य क्वेरी ऑब्जेक्ट को बदलने के लिए मजबूर करते हैं। (वर्डप्रेस वास्तव में एक दूसरी क्वेरी बनाता है, और ओवरराइट करता है $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' );
इस तरह, वर्डप्रेस पहले से ही संशोधित $wp_query
ऑब्जेक्ट का उपयोग करेगा जब पेजिंग का निर्धारण किया जाएगा, जिसमें कोई टेम्पलेट संशोधन की आवश्यकता नहीं होगी।
कब किस फंक्शन का इस्तेमाल करें
अनुसंधान इस सवाल-जवाब और इस सवाल-जवाब समझने के लिए कैसे और कब उपयोग करने के लिए WP_Query
, pre_get_posts
और query_posts()
।