कस्टम पोस्ट प्रकार द्वारा get_terms


19

मेरे पास दो कस्टम पोस्ट प्रकार 'देश' और 'शहर' हैं और एक साझा वर्गीकरण 'ध्वज' है।

अगर मैं उपयोग करता हूं:

<?php $flags = get_terms('flag', 'orderby=name&hide_empty=0');

मुझे वर्गीकरण में सभी शर्तों की एक सूची मिलती है, लेकिन मैं सूची को पोस्ट प्रकार 'देश' तक सीमित करना चाहता हूं।

मैं यह कैसे कर सकता हूं?


नए समाधान का उपयोग करना

<?php 
$flags = wpse57444_get_terms('flags',array('parent' => 0,'hide_empty' => 1,'post_types' =>array('country')));
foreach ($flags as $flag) {
    $childTerms = wpse57444_get_terms('flags',array('parent' => $flag->term_id,'hide_empty' => 1,'post_types' =>array('country')));
    foreach ($childTerms as $childTerm) {
        echo $childTerm->name.'<br />';
    }
}
?>

मैं $ childTerm-> नाम नहीं गूँज सकता। क्यों?


क्या आप थोड़ा स्पष्ट हो सकते हैं?
TheDeadMedic

जवाबों:


16

मुझे डर है कि यह देशी (अभी तक?) संभव नहीं है। यह ट्रेक देखें: http://core.trac.wordpress.org/ticket/18106

इसी तरह टैक्सोनॉमी एडमिन पेज पर पोस्ट की गिनती सभी पोस्ट प्रकारों को दर्शाती है । ( मुझे पूरा यकीन है कि इसके लिए एक टीआरसी टिकट भी है ) http://core.trac.wordpress.org/ticket/14084

इस संबंधित पोस्ट को भी देखें ।


नया उपाय

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

फ़ंक्शन के रूप में एक ही तर्क लेता है get_terms($taxonomies, $args)$argsअतिरिक्त तर्क लेता है, post_typesजिसमें एक सरणी होती है। पोस्ट प्रकारों की स्ट्रिंग।

लेकिन मैं इस बात पर ज़ोर नहीं दे सकता कि सब कुछ 'उम्मीद के मुताबिक' काम कर रहा है (मैं सोच रहा हूं कि गिनती गिन रहा हूं)। यह केवल डिफ़ॉल्ट के $argsलिए काम करते हुए दिखाई देता है get_terms

function wpse57444_get_terms( $taxonomies, $args=array() ){
    //Parse $args in case its a query string.
    $args = wp_parse_args($args);

    if( !empty($args['post_types']) ){
        $args['post_types'] = (array) $args['post_types'];
        add_filter( 'terms_clauses','wpse_filter_terms_by_cpt',10,3);

        function wpse_filter_terms_by_cpt( $pieces, $tax, $args){
            global $wpdb;

            // Don't use db count
            $pieces['fields'] .=", COUNT(*) " ;

            //Join extra tables to restrict by post type.
            $pieces['join'] .=" INNER JOIN $wpdb->term_relationships AS r ON r.term_taxonomy_id = tt.term_taxonomy_id 
                                INNER JOIN $wpdb->posts AS p ON p.ID = r.object_id ";

            // Restrict by post type and Group by term_id for COUNTing.
            $post_types_str = implode(',',$args['post_types']);
            $pieces['where'].= $wpdb->prepare(" AND p.post_type IN(%s) GROUP BY t.term_id", $post_types_str);

            remove_filter( current_filter(), __FUNCTION__ );
            return $pieces;
        }
    } // endif post_types set

    return get_terms($taxonomies, $args);           
}

प्रयोग

$args =array(
    'hide_empty' => 0,
    'post_types' =>array('country','city'),
);

$terms = wpse57444_get_terms('flag',$args);

मूल काम-काज

उपरोक्त टीआरसी टिकट से प्रेरित, (परीक्षण, और यह मेरे लिए काम करता है)

function wpse57444_filter_terms_by_cpt($taxonomy, $post_types=array() ){
    global $wpdb;

    $post_types=(array) $post_types;
    $key = 'wpse_terms'.md5($taxonomy.serialize($post_types));
    $results = wp_cache_get($key);

    if ( false === $results ) {
       $where =" WHERE 1=1";
       if( !empty($post_types) ){
            $post_types_str = implode(',',$post_types);
            $where.= $wpdb->prepare(" AND p.post_type IN(%s)", $post_types_str);
       }

       $where .= $wpdb->prepare(" AND tt.taxonomy = %s",$taxonomy);

       $query = "
          SELECT t.*, COUNT(*) 
          FROM $wpdb->terms AS t 
          INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id 
          INNER JOIN $wpdb->term_relationships AS r ON r.term_taxonomy_id = tt.term_taxonomy_id 
          INNER JOIN $wpdb->posts AS p ON p.ID = r.object_id 
          $where
          GROUP BY t.term_id";

       $results = $wpdb->get_results( $query );
       wp_cache_set( $key, $results );
    }        

    return $results;
}

प्रयोग

 $terms = wpse57444_filter_terms_by_cpt('flag',array('country','city'));

या

 $terms = wpse57444_filter_terms_by_cpt('flag','country');

यह काम करता है, लेकिन मैं अपने $ args के साथ क्या कर सकता हूं? मेरा मतलब है ... माता-पिता = 0 और ऑर्डरबी = नाम और छिपाने_मैं = 0
user1443216

नहीं - यह एक सरणी है $args = array('parent'=>0,'orderby'=>'name','hide_empty'=>0);:। मैं क्वेरी स्ट्रिंग्स की अनुमति देने के लिए इसे संपादित करूंगा ...
स्टीफन हैरिस

मैं इस उदाहरण में अपना $ args कहां रख सकता हूं $terms = wpse57444_filter_terms_by_cpt('flag',array('country','city'));:?
user1443216

आप केवल नए समाधान में उस एक में नहीं हो सकते:wpse57444_get_terms()
स्टीफन हैरिस

@ user1443216 $argsदूसरा तर्क है। वहाँ आप बसwpse57444_get_terms( 'flag', array( 'country', 'city' ) );
kaiser

2

@ स्टीफन-हैरिस के उत्तर के ऊपर केवल मेरे लिए आंशिक रूप से काम किया। अगर मैंने इसे पृष्ठ पर दो बार उपयोग करने की कोशिश की, तो यह काम नहीं किया। इसके अलावा, इस तरह के mysql प्रश्नों को दफनाने का विचार मुझे चिंतित करता है - मुझे लगता है कि भविष्य के WP अपडेट के साथ संघर्ष से बचने के लिए, समाधान प्राप्त करने के लिए कोर विधियों का उपयोग करना बेहतर होगा। यहाँ मेरा समाधान है, ट्रेस टिकट पर कुछ टिप्पणी # 7 के आधार पर वह संदर्भ

function get_terms_by_custom_post_type( $post_type, $taxonomy ){
  $args = array( 'post_type' => $post_type);
  $loop = new WP_Query( $args );
  $postids = array();
  // build an array of post IDs
  while ( $loop->have_posts() ) : $loop->the_post();
    array_push($postids, get_the_ID());
  endwhile;
  // get taxonomy values based on array of IDs
  $regions = wp_get_object_terms( $postids,  $taxonomy );
  return $regions;
}

उपयोग:

$terms = get_terms_by_custom_post_type('country','flag');

यह केवल एक पोस्ट प्रकार और एक टैक्सोनॉमी के लिए काम करता है, क्योंकि यह वही है जो मुझे चाहिए था, लेकिन इन मूल्यों को स्वीकार करने के लिए इसे संशोधित करना बहुत कठिन नहीं होगा।

उस Trac थ्रेड पर कुछ उल्लेख था कि यह अच्छी तरह से पैमाने पर नहीं हो सकता है, लेकिन मैं बहुत छोटे पैमाने पर काम कर रहा हूं और गति के साथ कोई समस्या नहीं है।


यह समाधान mee - anyways के लिए अधिक "मूल" दिखता है -> आपको लूप के "अंतिम" के बाद "wp_reset_postdata ()" कॉल करना चाहिए: wordpress.stackexchange.com/questions/144343/…
थॉमस फेलिंगर

2

दो कस्टम पोस्ट प्रकार 'देश' और 'शहर' और एक साझा वर्गीकरण 'ध्वज'। आप सूची को पोस्ट प्रकार 'देश' तक सीमित रखना चाहते हैं।

यहाँ एक और अधिक सरल उपाय है:

$posts_in_post_type = get_posts( array(
    'fields' => 'ids',
    'post_type' => 'country',
    'posts_per_page' => -1,
) );
$terms = wp_get_object_terms( $posts_in_post_type, 'flag', array( 'ids' ) ); ?>

1

[संपादित करें] यह स्टीफन हैरिस के उत्कृष्ट जवाब पर एक टिप्पणी है।

अगर यह इस तरह के कई पोस्ट प्रकारों के साथ उपयोग किया जाता है तो यह किसी भी शब्द को वापस नहीं करता है $flags = wpse57444_get_terms('flags', array('post_types' => array('country','city')));। ऐसा इसलिए है क्योंकि $ wpdb-> तैयार $ post_types_str स्ट्रिंग को sanitizes p.post_type IN('country,city')जबकि यह होना चाहिए p.post_type IN('country','city')। इस टिकट को देखें: 11102 । इस विषय से समाधान का उपयोग इस के आसपास पाने के लिए करें: /programming//a/10634225


1

मैंने @ स्टेफेन हैरिस के उत्तर का उपयोग करने की भी कोशिश की, लेकिन मुझे जिस क्वेरी की आवश्यकता थी, वह एक ही क्वेरी के रूप में लिखना और फ़िल्टर टुकड़ों का उपयोग करना काफी कठिन था।

इसके अलावा, मुझे एक ही पृष्ठ में कई बार उस फ़ंक्शन का उपयोग करने की आवश्यकता थी और मैंने wpse_filter_terms_by_cptरैपर फ़ंक्शन के बाहर फ़ंक्शन की घोषणा करने वाली समस्या को हल किया ।

वैसे भी मेरी राय में @Mark Pruce का जवाब बेहतर है, उन्हीं कारणों के लिए उन्होंने कहा, भले ही इसके लिए आपको wp_get_object_termsफ़ंक्शन के लिए args तैयार करने के लिए एक और क्वेरी (और संबंधित लूप) बनाने की आवश्यकता हो ।

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