क्या मुझे प्री गेट पोस्ट या WP_Query का उपयोग करना चाहिए


29

मेरे पास निम्नलिखित क्वेरी है जिसे मैं अपने taxonomy.php टेम्पलेट के माध्यम से कॉल करता हूं query_brands_geo('dealers', 'publish', '1', $taxtype, $geo, $brands);

यह फ़ंक्शन पूरी तरह से काम करता है। हालाँकि, क्वेरी पोस्ट के लिए कोडेक्स पढ़ने के बाद, यह डिफ़ॉल्ट क्वेरी को बदलने के लिए पसंदीदा तरीका के रूप में pre_get_posts का उल्लेख करता है। क्या pre_get_posts अधिक कुशल होंगे तो नीचे मेरा wp_query फ़ंक्शन?

यदि ऐसा है तो मैं पूर्व_गीत_प्रस्ताव का निर्माण कैसे करूंगा और अपना चर और प्रश्न नीचे लिखूंगा?

function my_custom_query($posttype, $poststatus, $paidvalue, $taxtype, $geo, $brands) {
   global $wp_query; 
   $wp_query = new WP_Query();
   $args = array( 
      'post_type' => $posttype, 
      'post_status' => array($poststatus), 
      'orderby' => 'rand', 
      'posts_per_page' => 30, 
      'meta_query' => array( 
         array( 
            'key' => 'wpcf-paid', 
            'value' => array($paidvalue), 
            'compare' => 'IN', 
            ) 
      ), 
      'tax_query' => array( 
         'relation' => 'AND', 
         array( 
            'taxonomy' => $taxtype, 
            'field' => 'slug', 
            'terms' => $geo 
         ), 
         array( 
            'taxonomy' => 'brands', 
            'field' => 'slug', 
            'terms' => $brands 
         ) 
      ) 
   ); 

   return $wp_query->query($args); 
} 

जवाबों:


14

pre_get_postsएक ही क्वेरी चलाएगा, इसलिए दोनों को एक ही समय लगेगा। लेकिन, यदि आप pre_get_postsकार्रवाई का उपयोग करते हैं तो आप एक या अधिक एसक्यूएल प्रश्नों को बचाएंगे। अभी, वर्डप्रेस डिफ़ॉल्ट क्वेरी चला रहा है और फिर आप इस फ़ंक्शन के साथ अपनी क्वेरी चलाते हैं जो डिफ़ॉल्ट क्वेरी के परिणामों को प्रतिस्थापित करता है (परिणामस्वरूप, डिफ़ॉल्ट क्वेरी का कोई फायदा नहीं है)। नीचे बताया गया है कि आप कैसे अपने कदम बढ़ा सकते $argsहैं

function custom_pre_get_posts($query, $posttype='dealers', $poststatus='publish', $paidvalue='1', $taxtype='any_default_value', $geo='any_default_value', $brands='any_default_value') {

    // filter your request here.
    if($query->is_category) {

        $args = array(
            'post_type' => $posttype,
            'post_status' => array($poststatus),
            'orderby' => 'rand',
            'posts_per_page' => 30,
            'meta_query' => array(
                array(
                    'key' => 'wpcf-paid',
                    'value' => array($paidvalue),
                    'compare' => 'IN',
                )
            ),
            'tax_query' => array(
                'relation' => 'AND',
                array(
                    'taxonomy' => $taxtype,
                    'field' => 'slug',
                    'terms' => $geo
                ),
                array(
                    'taxonomy' => 'brands',
                    'field' => 'slug',
                    'terms' => $brands
                )
            )
        );
        $query->query_vars = $args;
    }
}
add_action('pre_get_posts', 'custom_pre_get_posts');

उत्तर के लिए बहुत - बहुत धन्यवाद। यह बहुत ही उपयोगी है। एक त्वरित प्रश्न। मैंने अपने थीम function.php फ़ाइल में फ़ंक्शन रखा। मैं अपने taxonomy.php से इस फ़ंक्शन को custom_pre_get_posts ($ क्वेरी) चलाता हूं। Taxonomy.php में मैंने चर, $ posttype, $ post_status, $ geo, $ ब्रांड्स, $ taxtype की स्थापना की और इन चर को बदलने वाले दो लूप चलाए। क्या वहाँ एक तरीका है जो करोनॉमी.फपी से उपरोक्त कार्य में परिवर्तनशील है? जब मैं custom_pre_get_posts ($ क्वेरी, 'डीलर', 'प्रकाशित', '1', $ टैक्सटाइप, $ जियो, $ ब्रांड) की कोशिश करता हूं; मुझे custom_pre_get_posts () के लिए 2 तर्क 7 के माध्यम से अनुपलब्ध है। मैं add_action के कारण मानता हूं ???
user1609391

1
मैं मान रहा हूँ कि आपने शेष तर्कों को स्वीकार करने के लिए custom_pre_get_posts को बदल दिया है। हां, आपको add_action के कारण त्रुटि हो रही है। add_action इस फ़ंक्शन को एकल तर्क (यानी $ क्वेरी) के साथ कहता है, आपको लापता तर्क त्रुटियों से बचने के लिए अन्य तर्कों को डिफ़ॉल्ट मान देना चाहिए। जैसे ($ posttype = null, $ poststatus = null ...) इसलिए इसे ठीक से add_action करके बुलाया जा सकता है।
MR

MR उत्तर के लिए धन्यवाद। मैं ऐड एक्शन पर पढ़ता हूं और मुझे लगता है कि मुझे एक प्राथमिकता और तर्क संख्या प्रदान करनी चाहिए। इसलिए मैंने अपनी ऐड एक्शन को <code> add_action ('pre_get_posts', 'custom_pre_get_posts', 10,7) में बदल दिया; </ code> फिर अपने taxonomy.php पेज में I <कोड: do_action ('pre_get_post', $ क्वेरी, ' डीलर ',' प्रकाशित ',' 1 ', $ टैक्सेप्ट, $ जियो, $ ब्रांड) </ code>। लेकिन मुझे अभी भी वही त्रुटि मिल रही है। मैं निश्चित नहीं था कि डिफ़ॉल्ट मान कहाँ रखा जाए। मैंने Google की कोशिश की, लेकिन एक संदर्भ नहीं मिला। क्या आप मुझे इस बारे में थोड़ी और जानकारी दे सकते हैं कि इसे कैसे संभालना है?
user1609391

उत्तर और उदाहरण के लिए धन्यवाद। लेकिन मुझे लगता है कि मैं pre_get_posts का उपयोग करने की कोशिश कर सकता हूं, जब मुझे बस एक नया वर्डप्रेस क्वेरी करना चाहिए। मैं एक क्वेरी को बचाने की कोशिश कर रहा था, लेकिन मेरे मामले में यह संभव नहीं हो सकता है। इसका कारण यह है कि आप पैरामीटर में सेट किए गए सभी तर्क हैं, मैं अपनी taxonomy.php फ़ाइल से फ़ंक्शन को पास करना चाहता था। तो $ payvalue = "1" 1 या 0 हो सकता है, जो इस बात पर निर्भर करता है कि मैं taxonomy.php में किस शर्त पर अमल कर रहा हूं। ऐसा लगता है कि पृष्ठ के ऊपर प्रायर_गेट_पॉस्ट तब होता है जब पेज लोड होता है, भले ही मैं अपने टैक्सोनॉमी.पैप फ़ाइल में फ़ंक्शन को कॉल नहीं करता हूं। क्या मैं इसे सही देख रहा हूँ?
user1609391

3
यह उत्तर गैर-समझदार है जैसा कि वर्तमान में लिखा गया है। आप वस्तु के अंदर किसी भी मूल्य को अधिलेखित कर देंगे $wp_queryऔर चीजें पूरी तरह से विफल हो जाएंगी। इसके अलावा यह बस सच नहीं है कि pre_get_postsएक अतिरिक्त क्वेरी चलेगी ...
15'13 को kaiser

10

सबसे उत्कीर्ण जवाब के रूप में देर से जवाब आपकी क्वेरी को तोड़ देगा और बस कुछ प्रमुख बिंदुओं में सच नहीं है।

मुख्य WP_Query और यह फिल्टर

सबसे पहले, वर्डप्रेस आंतरिक रूप से उपयोग करता है query_posts()(एक पतली आवरण जो WP_Queryकि थीम या प्लगइन्स में उपयोग नहीं किया जाना चाहिए ) ए WP_Query। यह WP_Queryमुख्य लूप / क्वेरी के रूप में कार्य कर रहा है। जब तक वास्तविक SQL क्वेरी स्ट्रिंग का निर्माण नहीं किया जाता है तब तक यह क्वेरी बहुत सारे फ़िल्टर और क्रियाओं के माध्यम से चलेगी। उनमें से एक है pre_get_posts। अन्य हैं posts_clauses, posts_whereआदि, कि आपको क्वेरी स्ट्रिंग निर्माण प्रक्रिया को बाधित करने की भी अनुमति देते हैं।

गहराई से देखें कि कोर के अंदर क्या होता है

वर्डप्रेस wp()फ़ंक्शन (इन wp-includes/functions.php) चलाता है , जो कॉल करता है $wp->main()( $wpवर्ग WP की एक वस्तु है, जिसे में परिभाषित किया गया हैwp-includes/class-wp.php )। यह वर्डप्रेस को बताता है:

  1. उपयोग करके क्वेरी विनिर्देश में URL को पार्स करें WP->parse_request() - उस पर और नीचे।
  2. सभी is_ वैरिएबल सेट करें जिनका उपयोग सशर्त टैग द्वारा किया जाता है $wp_query->parse_query()( $wp_queryयह एक वस्तु है class WP_Query, जिसे परिभाषित किया गया है wp-includes/query.php)। ध्यान दें कि इस फ़ंक्शन के नाम के बावजूद, इस मामले मेंWP_Query->parse_query वास्तव में हमारे लिए कोई पार्सिंग नहीं करता है, क्योंकि इससे पहले हाथ से किया जाता है WP->parse_request()
  3. फ़ंक्शन स्पेसिफिकेशन को MySQL डेटाबेस क्वेरी में कनवर्ट करें, और WP_Query-> get_posts () में पदों की सूची प्राप्त करने के लिए डेटाबेस क्वेरी चलाएँ। वर्डप्रेस लूप में उपयोग किए जाने वाले $ wp_query ऑब्जेक्ट में पोस्ट सहेजें।

स्रोत कोडेक्स

निष्कर्ष

यदि आप वास्तव में मुख्य क्वेरी को संशोधित करना चाहते हैं, तो आप विभिन्न प्रकार के फ़िल्टर का उपयोग कर सकते हैं। बस वहां डेटा बदलने के$query->set( 'some_key', 'some_value' ); लिए उपयोग करें या सशर्त जांच करने के लिए डेटा पुनर्प्राप्त करने के लिए उपयोग करें । यह आपको दूसरी क्वेरी करने से बचाएगा, क्योंकि आप SQL क्वेरी को केवल बदल रहे हैं ।$query->get( 'some_key' );

यदि आपको कोई अतिरिक्त क्वेरी करनी है , तो किसी WP_Queryऑब्जेक्ट के साथ जाएं । इससे DB में एक और क्वेरी जुड़ जाएगी।

उदाहरण

जैसा कि उत्तर हमेशा एक उदाहरण के साथ बेहतर काम करते हैं, आपको यहां एक बहुत अच्छा मिला (प्रॉप टू ब्रैड टूसेनार्ड), जो बस कोर ऑब्जेक्ट को बढ़ाता है और इसलिए बहुत पुन: प्रयोज्य है (इसमें से एक प्लगइन बनाएं):

class My_Book_Query extends WP_Query
{
    function __construct( $args = array() )
    {
        // Forced/default args
        $args = array_merge( $args, array(
            'posts_per_page' => -1
        ) );

        add_filter( 'posts_fields', array( $this, 'posts_fields' ) );

        parent::__construct( $args );
    }

    public function posts_fields( $sql )
    {
        return "{$sql}, {$GLOBALS['wpdb']->terms}.name AS 'book_category'";
    }
}

फिर आप अपनी दूसरी / अतिरिक्त क्वेरी चला सकते हैं जैसे आप निम्नलिखित उदाहरण में देख सकते हैं। अपनी क्वेरी को बाद में रीसेट करना न भूलें।

$book_query = new My_Book_Query();
if ( $book_query->have_posts() )
{
    while ( $book_query->have_posts() )
    {
        $book_query->the_post();
        # ...do stuff...
    } // endwhile;
    wp_reset_postdata();
} // endif;

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.