क्या मैं pre_get_posts फ़ंक्शन का उपयोग करके मेटा कुंजी द्वारा एक पोस्ट को बाहर कर सकता हूं?


24

मैं देखता हूं कि बहुत से लोग pre_get_postsहुक का उपयोग करना पसंद करते हैं query_posts। नीचे दिया गया कोड काम करता है और सभी पोस्ट दिखाता है जिसमें मेटा कुंजी "चित्रित" है

function show_featured_posts ( $query ) {
    if ( $query->is_main_query() ) {
       $query->set( 'meta_key', 'featured' );
       $query->set( 'meta_value', 'yes' );
    }
}

add_action( 'pre_get_posts', 'show_featured_posts' );

लेकिन मैं चाहता हूं कि जिन पोस्टों में मुख्य क्वेरी से featured'मेटा_की' को बाहर रखा जाए । क्या इसके लिए कोई आसान तरीका है?

जवाबों:


33

मैं देखता हूं कि बहुत से लोग query_posts के बजाय pre_get_posts हुक का उपयोग करना पसंद करते हैं

वाह!

तो pre_get_postsएक WP_Queryवस्तु को फ़िल्टर करता है जिसका अर्थ है कि आप जो कुछ भी आप कर query_posts()सकते हैं वह आप के माध्यम से कर सकते हैं $query->set()और $query->get()। विशेष रूप से हम meta_queryविशेषता का उपयोग कर सकते हैं ( कोडेक्स देखें ):

$meta_query = array(
                 array(
                    'key'=>'featured',
                    'value'=>'yes',
                    'compare'=>'!=',
                 ),
);
$query->set('meta_query',$meta_query);

लेकिन .. यह मूल 'मेटा क्वेरी' (यदि यह एक था) की जगह लेता है। इसलिए जब तक आप मूल मेटा क्वेरी को पूरी तरह से बदलना नहीं चाहते, मैं सुझाव देता हूं:

//Get original meta query
$meta_query = $query->get('meta_query');

//Add our meta query to the original meta queries
$meta_query[] = array(
                    'key'=>'featured',
                    'value'=>'yes',
                    'compare'=>'!=',
                );
$query->set('meta_query',$meta_query);

इस तरह हम मौजूदा मेटा क्वेरीज़ के साथ अपनी मेटा क्वेरी जोड़ते हैं।

आप ( या सभी को संतुष्ट करने वाले पोस्ट वापस करने relationके $meta_queryलिए ANDया ORकम से कम एक, मेटा क्वेरीज़) की संपत्ति सेट या करना चाह सकते हैं / कर सकते हैं ।

* नोट: इस प्रकार की क्वेरी 'विशेष रुप से प्रदर्शित' मेटा कुंजी के साथ पोस्ट लौटाएगी, लेकिन जिसका मूल्य नहीं है yes। इसमें वे पद शामिल नहीं होंगे जहाँ 'विशेष रुप से प्रदर्शित' मेटा कुंजी मौजूद नहीं है। आप 3.5 में ऐसा कर पाएंगे


तो यह जांचने का कोई तरीका नहीं है कि किसी पोस्ट के लिए मेटा_की मौजूद है या नहीं / खाली है या नहीं? मुझे 3.5 इंतजार करना होगा। फिर। आपके जवाब के लिए धन्यवाद।
कार्लिस्ले

मैं बस के साथ एक मेटा बॉक्स का निर्माण करेगा Yesऔर Noविकल्प और 'नहीं' डिफ़ॉल्ट रूप से चयन किया जाएगा। जब मुझे एक पोस्ट की सुविधा चाहिए तो मैं चयन करूँगा Yes। हालाँकि, मैं चाहता हूं कि अंतिम 5 पोस्ट विशेष रुप से प्रदर्शित रहें और अन्य मुख्य क्वेरी पर प्रदर्शित हों। मैं वापस नहीं जाना चाहता और चयन को हर बार बदलना चाहता हूं, इसलिए मुझे केवल सबसे हाल के 5 पदों को बाहर करने का रास्ता खोजना होगा। मुझे स्टैकएक्सचेंज पर इसी तरह के कई प्रश्न दिखाई देते हैं और उन चित्रित पोस्ट को प्रबंधित करने का एक आसान तरीका होना चाहिए। (एक तरीका जो सामान्य प्रदर्शन को प्रभावित नहीं करता है, बहुत सारे प्रश्नों का निर्माण नहीं करता है या मिश्रित एसक्यूएल प्रश्नों की आवश्यकता नहीं है)
कार्लिस्ले

BTW मुझे यकीन नहीं है कि सभी पोस्ट के लिए अतिरिक्त मेटा_की Yesया Noमान बनाने के लिए यह एक अच्छा विचार है । यह उन पदों को बाहर करने के लिए बहुत अच्छा होगा, जिनमें केवल featuredकुंजी की कमी है ।
कार्लिसल

यह फ़ंक्शन केवल मेरी साइट पर टूट गया था Uncaught Error: [] operator not supported for stringsक्योंकि PHP 7 में अपग्रेड करने के बाद एक त्रुटि थी क्योंकि मूल meta_queryवापस शून्य के रूप में आ रहा था। यदि कोई भी बाहर के $meta_query = $query->get('meta_query');लिए स्विचन मौजूद नहीं है, तो आप एक खाली सरणी में वापस गिरकर इसे प्राप्त कर सकते हैं $meta_query = ( is_array( $query->get('meta_query') ) ) ? $query->get('meta_query') : [];
केविन नगेंट

2

यदि कुछ लोग इसका उपयोग कर सकते हैं, तो मैं विशेष रुप से चित्रित पदों के लिए अपना अस्थायी समाधान पोस्ट करना चाहता हूं। मैं pre_get_postsयहाँ हुक का उपयोग नहीं करता, लेकिन query_postsया तो नहीं । समस्या यह है कि मुझे मुख्य क्वेरी के साथ खेलना होगा और एसक्यूएल क्वेरी का एक टुकड़ा चलाना होगा। मुझे खुशी होगी अगर कोई विशेषज्ञ कोड की जांच कर सकता है और मुझे बता सकता है कि क्या यह ठीक है और किसी भी प्रदर्शन के मुद्दों का कारण नहीं होगा। यह भी बहुत अच्छा होगा यदि किसी के पास बेहतर दृष्टिकोण हो और वह हमारे साथ साझा करे।

चुनिंदा पोस्ट क्वेरी बनाएँ

<?php 

$featured_query = new WP_query( array(
    'meta_key'       =>'featured', 
    'meta_value'     =>'yes', 
    'posts_per_page' => 5, 
    'no_found_rows'  => true
    )
);

while ($featured_query->have_posts()) : 

    $featured_query->the_post(); 
    //Stuff...

endwhile; 
wp_reset_postdata(); 

?>

मुख्य क्वेरी बनाएं, जिन पोस्टों में विशेष रूप से मेटा_की है, उन्हें बाहर करें, बहिष्करण को 5 सबसे हाल के पोस्टों तक सीमित करें और अन्य सभी को दिखाएं।

<?php 

$excludeposts = $wpdb->get_col( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = 'featured' AND meta_value != '' ORDER BY post_id DESC LIMIT 0, 5" );

$main_query = new WP_Query( array(
    'post__not_in' => $excludeposts, 
    'paged' => $paged 
    ) 
);  

while ($main_query->have_posts()) : 

    $main_query->the_post();
    //Stuff...

endwhile;

?>

0

जवाब में @ कार्लिस्ले, यदि आप विशेष रूप से चिह्नित 5 सबसे हाल के पोस्ट को बाहर करना चाहते हैं, तो आप निम्न कार्य कर सकते हैं। उन पोस्ट_पर_पृष्ठ को बदलें जिन्हें आप बहिष्कृत करना चाहते हैं, और मेटा श्रेणी से आप कैसे चित्रित श्रेणी को निर्दिष्ट कर रहे हैं।

function cmp_exclude_featured_posts($query) {
    $exclude = array();  //Create empty array for post ids to exclude
    if ( $query->is_main_query() ) {
            $featured = get_posts(array(
                'post_type' => 'post',
                'meta_query' => array(
                    array(
                        'key' => 'featured',
                        'value' => '1',
                        'compare' => '==',
                    ),
                ),
                'posts_per_page' => 2
            ));

            foreach($featured as $hide) {
                $exclude[] = $hide->ID;
            }   

            $query->set('post__not_in', $exclude);
        }
}

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