हाइलाइटिंग wp_nav_menu () पूर्वजों की कक्षा w / o नव संरचना में बच्चे?


30

( मॉडरेटर नोट: मूल रूप से "wp_nav_menu पूर्वज वर्ग नेविगेशन संरचना में बच्चों के बिना" शीर्षक था)

wp_nav_menuमेरे हेडर में एक है , जिसमें तीन पृष्ठ थे। जब मैं उन पृष्ठों में से एक पर होता हूं, liतो मेनू में उस पृष्ठ को वर्ग प्राप्त होता है .current_page_item। इन तीन पन्नों में टेम्प्लेट हैं, और इन टेम्प्लेट में एक निश्चित सामग्री प्रकार के सभी पोस्ट प्राप्त करने के लिए कस्टम क्वेरी हैं। वास्तव में, इस शीर्ष स्तर पृष्ठ के कथित "बच्चे" वास्तव में बच्चे नहीं हैं, वे केवल उस सामग्री प्रकार के हैं जिसे मैंने उस शीर्ष स्तर पृष्ठ के साथ एक टेम्पलेट का उपयोग करके जोड़ा है।

'current-ancestor'जब कोई उपयोगकर्ता किसी विशिष्ट पोस्ट प्रकार के एकल पृष्ठ को ब्राउज़ कर रहा हो, तब उस वर्ग को प्राप्त करने के लिए मैं शीर्ष स्तर के मेनू आइटमों को पसंद करूंगा , केवल उस पेज से संबंधित टेम्पलेट फ़ाइल में एक कस्टम क्वेरी में।

आशा है कि समझ में आता है - यदि नहीं, तो मुझे बताएं कि मैंने आपको कहां खो दिया है! किसी भी मदद की बहुत सराहना करते हैं।

विशेष जानकारी के लिए --Edited: उदाहरण के लिए, मैं नामक एक स्थैतिक पृष्ठ है कार्यशालाएं कि एक टेम्पलेट का उपयोग कर रहा है। इसका स्लग वर्कशॉप है । टेम्प्लेट में कस्टम get_posts फ़ंक्शन और इसके भीतर लूप होता है, जो कार्यशालाओं नामक एक कस्टम सामग्री प्रकार के सभी पोस्टों को खींचता और प्रदर्शित करता है । यदि मैं इनमें से किसी एक कार्यशाला के शीर्षक पर क्लिक करता हूं, तो मुझे उस सामग्री के पूर्ण अंश पर ले जाया जाता है। कस्टम पोस्ट प्रकार की पर्मलिंक संरचना कार्यशालाओं / पोस्टनाम पर सेट है, इसलिए जैसे ही उपयोगकर्ता इसे देखता है, सामग्री के ये टुकड़े वर्कशॉप पेज के बच्चे होते हैं, जब वास्तव में वे सभी एक सामग्री प्रकार के होते हैं लेकिन पेज से असंबंधित होते हैं। यह वह अंतर है जिसे मुझे मेनू में प्रभावी ढंग से बंद करने की आवश्यकता है, प्रकार की कार्यशाला की सामग्री ब्राउज़ करते समय 'कार्यशालाओं' मेनू आइटम को उजागर करना।

फिर से, आशा है कि समझ में आता है, मुझे लगता है कि मैंने एक पैराग्राफ में 20 बार 'वर्कशॉप' कहा!


@ गेविन - क्या आप जो पूरा करने की कोशिश कर रहे हैं, उसमें कुछ और बारीकियों को शामिल कर सकते हैं। यदि हम इसे सार में करने का प्रयास करते हैं तो इसकी तुलना में ठोस शब्दों में उत्तर लिखना आसान है। इसके अलावा अगर आप अपने URL संरचना को इन से संबंधित समझा सकता है यह उपयोगी होगा।
माइकस्किंकल

1
@ गेविन - यह मदद करता है। तो आपका शीर्ष स्तर मेनू विकल्प "वर्कशॉप" में कार्यशालाओं की एक सूची है जिसमें एक पथ है /workshops/और जब कोई उपयोगकर्ता एक वर्कशॉप पेज (यानी /workshops/example-workshop/) पर है तो आप "वर्कशॉप्स" मेनू आइटम को क्लास current_page_itemअसाइन करना चाहते हैं, सही है?
माइकस्किंकल

wp_nav_menu () वर्तमान-मेनू-पूर्वज वर्ग को उजागर करता है
डैनियल सैक्स

जवाबों:


29

एक सरल उपाय है। प्रत्येक पोस्ट प्रकार के लिए पृष्ठ बनाना भूल जाओ, ताकि आपके पास नौसेना के सामान हो सकें, क्योंकि जैसा कि आप सीख चुके हैं, WP में यह पहचानने का कोई तरीका नहीं है कि आप जिस कस्टम प्रकार को ब्राउज़ कर रहे हैं, वह उस पृष्ठ से संबंधित है।

इसके बजाय, प्रकटन-> मेनू में एक कस्टम लिंक बनाएं। बस वह URL डालें जो आपके कस्टम प्रकार को लौटाएगा और उसे एक लेबल देगा, फिर "Add to Menu" दबाएं।

http://example.com/workshops/

या गैर-सुंदर-पर्मलिंक्स:

http://example.com/?post_type=workshops

यह अकेला एक नेवी बटन बनाएगा, जो उस कस्टम पोस्ट प्रकार के साथ सभी पोस्ट प्रदर्शित करता है, और जब आप उस नेवी आइटम पर क्लिक करते हैं, तो वह वर्तमान-मेनू-आइटम क्लास को भी जोड़ देगा - लेकिन यह अभी तक किसी भी पर नेवी क्लास नहीं जोड़ेगा इस के अलावा अन्य URL

फिर, एक बार बनने के बाद, उस नए आइटम के लिए कॉन्फ़िगरेशन में जाएं, और "शीर्षक गुण" फ़ील्ड में कस्टम पोस्ट प्रकार के स्लग में प्रवेश करें (आप विवरण फ़ील्ड का उपयोग भी कर सकते हैं, लेकिन वह व्यवस्थापक स्क्रीन विकल्पों में छिपा है डिफ़ॉल्ट रूप से)।

अब, आपको nav_menu_css_classफ़िल्टर को हुक करने की आवश्यकता है (जो प्रत्येक नौसेना आइटम के लिए निकाल दिया जाता है) और जांचें कि क्या देखी जा रही सामग्री आपके कस्टम नेवी आइटम में संकेतित पोस्ट प्रकार की है:

add_filter('nav_menu_css_class', 'current_type_nav_class', 10, 2 );
function current_type_nav_class($classes, $item) {
    $post_type = get_query_var('post_type');
    if ($item->attr_title != '' && $item->attr_title == $post_type) {
        array_push($classes, 'current-menu-item');
    };
    return $classes;
}

इस मामले में, हम यह जाँचने जा रहे हैं कि शीर्षक गुण फ़ील्ड की सामग्री खाली नहीं है और यदि वे वर्तमान पोस्ट_टाइप से मेल खाते हैं तो उनका मिलान किया जाता है। यदि हां, तो हम वर्तमान-मेनू-आइटम वर्ग को उसके वर्ग सरणी में जोड़ते हैं, फिर संशोधित सरणी लौटाते हैं।

आप इसे केवल नौसेना आइटम के शीर्षक से मिलान करने के लिए संशोधित कर सकते हैं, लेकिन अगर किसी कारण से आप पोस्ट प्रकार के सादे स्लग की तुलना में अलग से नौसेना आइटम को शीर्षक देना चाहते हैं, तो शीर्षक विशेषता या विवरण फ़ील्ड का उपयोग करके आपको वह लचीलापन मिलता है।

अब जब भी आप किसी पोस्ट प्रकार के एक एकल आइटम (या शायद यहां तक ​​कि संग्रह लिस्टिंग) को देख रहे हैं जो एक नव मेनू आइटम से मेल खाता है, तो उस आइटम को सीएसएस वर्ग वर्तमान-मेनू-आइटम दिया जाएगा ताकि आपका हाइलाइटिंग काम करेगा।

कोई पेज या पेज टेम्प्लेट की जरूरत नहीं; ;-) क्वेरी क्वेरी सही पोस्ट लाने का ध्यान रखती है। आपका लूप टेम्प्लेट क्वेरी आउटपुट प्रदर्शित करने का ध्यान रखता है। यह फ़ंक्शन यह दर्शाता है कि क्या दिखाया जा रहा है और CSS वर्ग को जोड़ा जा रहा है।

बोनस

आप wp_update_nav_menu_itemअपने सभी प्रकार के पोस्ट के लिए मेनू आइटम स्वचालित रूप से जेनरेट करके भी प्रक्रिया का उपयोग कर सकते हैं। इस उदाहरण के लिए, आपको सबसे पहले $menu_idउस मेनू को पुनः प्राप्त करना होगा जिसे आप इस आइटम को जोड़ना चाहते हैं।

$types = get_post_types( array( 'exclude_from_search' => false, '_builtin' => false  ), 'objects' );
foreach ($types as $type) {
    wp_update_nav_menu_item( $menu_id, 0, array(
        'menu-item-type' => 'custom',
        'menu-item-title' => $type->labels->name,
        'menu-item-url' => get_bloginfo('url') . '/?post_type=' . $type->rewrite['slug'],
        'menu-item-attr-title' => $type->rewrite['slug'],
        'menu-item-status' => 'publish'
        )
    );
}

यह सब है! मैं केवल पेज टेम्प्लेट का उपयोग कर रहा हूं क्योंकि लेआउट उन पृष्ठों के लिए जटिल हैं और केवल पृष्ठों को सूचीबद्ध नहीं करते हैं, हालांकि मैं अभी भी उस फ़िल्टर का उपयोग कर सकता हूं जो आपने पृष्ठ आईडी की जांच के लिए प्रदान किया था। इस विषय की प्रकृति यह है कि थीम विकल्प आपको पृष्ठों से मेल खाने के लिए मिलता है ('घर' यह पृष्ठ है, 'इस पृष्ठ के बारे में है, आदि'), ताकि यह पूरी तरह से काम करे। (अविश्वसनीय रूप से विस्तृत) सहायता के लिए धन्यवाद!
गैविन

मुझे उस current_page_parentनेविगेशन आइटम से हटाना पड़ा जो मेरा ब्लॉग था - लेकिन अन्यथा यह काम करता था। thx
pkyeck

यह मेरे लिए काम नहीं कर रहा था, क्योंकि $item->attr_titleTITLE निकाला गया था, और मैंने शीर्षक बड़े अक्षरों में लिखा था। इसलिए मैंने इसके लिए विशेषता बदल दी $item->post_nameऔर अब यह मेरे लिए ठीक काम करता है।
honk31

मैंने अपनी थीम के लिए कोड काम करने की कोशिश की, लेकिन यह काम नहीं कर पाया। मेनू में मेरे मूल आइटम पर कोई वर्ग लागू नहीं होगा, जब मैं कस्टम पोस्ट प्रकार पर हूं portfolio। मैंने ऊपर कोड का उपयोग किया है। क्या समस्या हो सकती है?
कैस्पर

4

के बजाय का उपयोग करने का

$ post_type = get_query_var ('post_type');

आप कोशिश करना चाहते हो सकता है:

$ post_type = get_post_type ();

कुछ प्रकार के रूप में पोस्ट प्रकार क्वेरी संस्करण में सेट नहीं है। यह "पोस्ट" के डिफ़ॉल्ट पोस्ट_टाइप के लिए मामला है, इसलिए यदि आप किसी पोस्ट को सूचीबद्ध पृष्ठ से सूचीबद्ध करना चाहते हैं, तो आपको इसका उपयोग करने की आवश्यकता होगी। get_very_var () सिर्फ पोस्ट प्रकार के लिए एक खाली स्ट्रिंग देता है जो कस्टम नहीं हैं।

add_filter('nav_menu_css_class', 'current_type_nav_class', 10, 2 );
function current_type_nav_class($classes, $item) {
    $post_type = get_post_type();
    if ($item->attr_title != '' && $item->attr_title == $post_type) {
        array_push($classes, 'current-menu-item');
    };
    return $classes;
}

2

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

add_filter('nav_menu_css_class', 'current_type_nav_class', 10, 2 );
function current_type_nav_class($classes, $item) {

    # get Query Vars
    $post_type = get_query_var('post_type');  
    $taxonomy = get_query_var('taxonomy');

    # get and parse Title attribute of Menu item
    $title = $item->attr_title; // menu item Title attribute, as post_type;taxonomy
    $title_array = explode(";", $title);
    $title_posttype = $title_array[0];
    $title_taxonomy = $title_array[1];

    # add class if needed
    if ($title != '' && ($title_posttype == $post_type || $title_taxonomy == $taxonomy)) {
        array_push($classes, 'current-menu-item');
    };
    return $classes;
}

2

यदि आप wp_list_pages के साथ काम करना चाहते हैं तो यहां मेरा समाधान है।

इसे अपने कार्यों में जोड़ें

add_filter('page_css_class', 'my_page_css_class', 10, 2);
function my_page_css_class($css_class, $page){
    $post_type = get_post_type();
    if($post_type != "page"){
        $parent_page = get_option('page_for_custom_post_type-'.$post_type);
        if($page->ID == $parent_page)
            $css_class[] = 'current_page_parent';
    }
    return $css_class;
}

अब बस wp_options तालिका में पेज_for_custom_post_type-xxxx के एक विकल्प_नाम के साथ एक नई पंक्ति जोड़ें और पेज-आईडी के साथ एक विकल्प_वायु कनेक्ट करना चाहते हैं।

शायद आपने पहचाना कि पहले से ही page_for_posts नामक एक विकल्प है । यदि आपके पास केवल 1 कस्टम पोस्ट प्रकार है, तो यू आपके पेज को ड्रॉपडाउन में /wp-admin/options-reading.php पर सेट कर सकता है और नेविगेशन current_page को सही ढंग से सेट करेगा।

मुझे लगता है कि वर्डप्रेस कोर को इस अनुभाग को हर पोस्ट प्रकार के लिए एक ड्रॉपडाउन के साथ विस्तारित करना चाहिए।


2

मैंने पृष्ठों के साथ चिपके रहने और पृष्ठ आइटम नाम का उपयोग करने के लिए नौसेना आइटम पर एक वर्ग के रूप में निर्णय लिया। यह मुझे शीर्षक विशेषता को अव्यवस्थित करने से बचने की अनुमति देता है जो मुझे कुछ अन्य समाधानों के बारे में पसंद नहीं था।

add_filter('nav_menu_css_class', 'mbudm_add_page_type_to_menu', 10, 2 );
//If a menu item is a page then add the template name to it as a css class 
function mbudm_add_page_type_to_menu($classes, $item) {
    if($item->object == 'page'){
        $template_name = get_post_meta( $item->object_id, '_wp_page_template', true );
        $new_class =str_replace(".php","",$template_name);
        array_push($classes, $new_class);
        return $classes;
    }   
}

मैं शीर्ष लेख भी जोड़ रहा हूँ

<body <?php body_class(); ?>>

अंत में इस समाधान के लिए आपके नव मेनू आइटम में चयनित / सक्रिय राज्य को लागू करने के लिए कुछ अतिरिक्त सीएसएस की आवश्यकता होती है। मैं इसका उपयोग इस पृष्ठ के बच्चों के रूप में पृष्ठ से संबंधित टैक्सोनॉमी अभिलेखागार और कस्टम पोस्ट दिखाने के लिए करता हूं:

/* selected states - include sub pages for anything related to products */
#nav-main li.current-menu-item a,
body.single-mbudm_product #nav-main li.lp_products a,
body.tax-mbudm_product_category #nav-main li.lp_products a,
#nav-main li.current_page_parent a{color:#c00;}

इससे मुझे निम्नलिखित त्रुटि मिली: Warning: join() [function.join]: Invalid arguments passed in /home/path/to/wp-includes/nav-menu-template.php on line 76 कोई भी विचार यहां क्या हुआ?
जेफ के।

ओह मुझे लगता है कि मैं देख रहा हूं कि क्या हो रहा है। इसका कारण यह है कि यदि आप if स्टेटमेंट के भीतर $ कक्षाएं वापस कर रहे हैं। बस return $classesबाहर की ओर बढ़ना और उसके बाद ifउपरोक्त त्रुटि को हल करना प्रतीत होता है।
जेफ के।

1

@Somatic - महान कोड! मैंने खुद एक बदलाव किया। मैं अपने इच्छित उद्देश्य के लिए शीर्षक गुण को रखना चाहता था, इसलिए मैंने लिंक रिलेशनशिप (एक्सएफएन) उन्नत मेनू गुणों में कस्टम पोस्ट टाइप स्लग को रखा जिसे आप स्क्रीन विकल्प में सक्षम कर सकते हैं। मैंने संशोधित किया

if ($item->attr_title != '' && $item->attr_title == $post_type) {

और इसे बदल दिया

if ($item->xfn != '' && $item->xfn == $post_type) {

0

अच्छा काम दैहिक।

दुर्भाग्य से, मुझे नहीं लगता कि आप अपने कस्टम पोस्ट प्रकारों को किसी पृष्ठ पर उस तरह से सूचीबद्ध कर सकते हैं जिस तरह से आप समझाते हैं। अगर मैं किसी पेज-पोर्टफोलियो.फपी का उपयोग नहीं करता हूं और इसे एक पेज पर जोड़ता हूं, तो मुझे केवल 404 पेज मिलते हैं।

अगर मुझे Gavin पसंद है, तो मैंने संशोधित किया है कि आप इस तरह ब्लॉग पेज से "current_page_parent" को निकालने के लिए थोड़ा सा कार्य करते हैं।

add_filter('nav_menu_css_class', 'current_type_nav_class', 10, 2);
function current_type_nav_class($css_class, $item) {
$post_type = get_query_var('post_type');

if (get_post_type()=='portfolio') {
    $current_value = "current_page_parent"; 
    $css_class = array_filter($css_class, function ($element) use ($current_value) { return ($element != $current_value); } );
}

if ($item->attr_title != '' && $item->attr_title == $post_type) {       
    array_push($css_class, 'current_page_parent');
};
return $css_class;

}

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