डायनामिक रूप से मेनू आइटम wp_nav_menu से बाहर रखें


17

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

1। पृष्ठभूमि:

मैंने अपनी साइट पर WP कस्टम मेनू (wp_nav_menu) और jqDock का उपयोग करके एक डॉक मेनू को एक साथ रखा । चूंकि jqDock को अपने जादू को काम करने के लिए निरंतर छवियों या छवि लिंक की आवश्यकता होती है, इसलिए मैं एक कस्टम वॉकर का उपयोग कर रहा हूं ताकि नव-मेनू HTML आउटपुट इस तरह से स्मूथ दिखे:

<div id="menu-first" class="nav">
<a><img src="http://path/to/image-1.png"/></a>
<a><img src="http://path/to/image-2.png"/></a>
<a><img src="http://path/to/image-3.png"/></a>
etc...
</div>

मेरे कस्टम वॉकर के लिए कोड है:

class custom_nav_walker extends Walker_Nav_Menu 
{
    var $tree_type = array( 'post_type', 'taxonomy', 'custom' );
    var $db_fields = array( 'parent' => 'menu_item_parent', 'id' => 'db_id' );

    function start_lvl(&$output, $depth) {
        $indent = str_repeat("\t", $depth);
        $output .= "\n$indent<ul class=\"sub-menu\">\n";
    }

    function end_lvl(&$output, $depth) {
        $indent = str_repeat("\t", $depth);
        $output .= "$indent</ul>\n";
    }

    function start_el(&$output, $item, $depth, $args) {
        global $wp_query;
        $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';

        $class_names = $value = '';

        $classes = empty( $item->classes ) ? array() : (array) $item->classes;
        $classes[] = 'menu-item-' . $item->ID;

        $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args ) );
        $class_names = ' class="' . esc_attr( $class_names ) . '"';

        $id = apply_filters( 'nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args );
        $id = strlen( $id ) ? ' id="' . esc_attr( $id ) . '"' : '';

        //$output .= $indent . '<li' . $id . $value . $class_names .'>';

        $attributes  = ! empty( $item->attr_title ) ? ' title="'  . esc_attr( $item->attr_title ) .'"' : '';
        $attributes .= ! empty( $item->target )     ? ' target="' . esc_attr( $item->target     ) .'"' : '';
        $attributes .= ! empty( $item->xfn )        ? ' rel="'    . esc_attr( $item->xfn        ) .'"' : '';
        $attributes .= ! empty( $item->url )        ? ' href="'   . esc_attr( $item->url        ) .'"' : '';

        $description  = ! empty( $item->description ) ? esc_attr( strtolower( $item->description )) : '';
        $item_title   = ! empty( $item->attr_title )  ? esc_attr( $item->attr_title ) : '';

        if ( strpos($description, ';') !== false ) {
        $description_array = explode (';', $description);
            $image_name = $description_array[0];
            $image_alt = $description_array[1];
        } else {
            $image_name = $description;
            $image_alt = $item_title;
        }

        $item_output = $args->before;
        $item_output .= '<a'. $attributes .'>';
        $item_output .= $args->link_before .'<img src="'.get_bloginfo('template_url').'/images/skin1/'.$image_name.'" alt="'.$image_alt.'" title="'.$item_title.'" />'.$args->link_after;
        $item_output .= '</a>';
        $item_output .= $args->after;

        $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
    }

    function end_el(&$output, $item, $depth) {
        $output .= "";
    }

}

JqDock स्क्रिप्ट तब मेनू आईडी ('मेनू-प्रथम') को पकड़ती है और डॉक मेनू के साथ wp_nav_menu आउटपुट को बदल देती है। डॉक मेनू का एचटीएमएल आउटपुट जेकडॉक लोड करते समय निर्दिष्ट विकल्पों के आधार पर बदलता है।

2. प्रश्न:

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

3. अस्वीकृत समाधान:

ए। मुल्तानी मेनू: कई मेनू बनाना और बनाना और फिर उन्हें सशर्त रूप से कॉल करना काम कर सकता है; हालाँकि, मुझे नहीं लगता कि यह कई कारणों से एक आदर्श और न ही एक साफ समाधान है। साथ ही, एकाधिक मेनू को बनाए रखने या अद्यतन करने के लिए आसान नहीं है।

ख। रेगेक्स खोज और बदलें: यह मुझे हर बार जब मैं HTML आउटपुट संशोधित किया जाता है, तो मैं jqDock विकल्पों को बदलने के लिए सुई पैरामीटर को बदलने के लिए मजबूर कर सकता हूं।

सी। CSS 'डिस्प्ले' प्रॉपर्टी: CSS डिस्प्ले प्रॉपर्टी कार्यों के माध्यम से आइटमों को छिपाना, लेकिन चूंकि इसे jqDock मेनू आउटपुट पर लागू किया जाना है, इसलिए यह मेनू के विज़ुअल रेंडरिंग को प्रभावित करता है।

4. विफल समाधान:

ए। Wp_nav_menu_items को फ़िल्टर करें : मैंने '$ आइटम' वेरिएबल (स्ट्रिंग) को पकड़ने की कोशिश की और इसे निम्नलिखित कोड के साथ सशर्त टैग के माध्यम से अलग-अलग मान असाइन किया गया है:

function userf_dynamic_nav_menu ($items) {
    $items_array_home = explode('<a', $items);
    $items_array_nothome = $items_array_home;

    unset($items_array_home[1]);
    unset($items_array_nothome[2]);

    $items_home = implode('<a', $items_array_home);
    $items_nothome = implode('<a', $items_array_nothome);

    if ( is_home() ) {
        $items = $items_home;
    } else {
        $items = $items_nothome;
    }
    return $items;
}
add_filter('wp_nav_menu_first_items', 'userf_dynamic_nav_menu');

यह केवल आंशिक रूप से काम करता है, क्योंकि मेनू आइटम बदलते हैं, लेकिन सशर्त टैग को अनदेखा किया जाता है। मुझे लगता है कि यह समझ में आता है कि किस पल में फिल्टर लगाया जाता है।

ख। कस्टम नेवी मेनू फ़ंक्शन : मैंने अपना स्वयं का कस्टम नेवी मेनू फ़ंक्शन बनाने की कोशिश की, जो $ डिफॉल्ट्स सरणी में एक बहिष्कृत तर्क जोड़ने और wp_list_pagesअतिरिक्त तर्क को पॉप्युलेट करने के लिए इस थोड़े संशोधित कोड का उपयोग करने में सक्षम हो :

$exclude_array = ( $args->exclude ) ? explode(',', $args->exclude) : array();
$args->exclude = implode( ',', apply_filters('wp_nav_menu_excludes', $exclude_array) );

कोई विचार?


क्या आप हमें अपना कस्टम वॉकर चाइल्ड क्लास दिखा सकते हैं?
आत्मासेकाह

हाय सोलेसेका, मैंने इसे अपने मूल पद में जोड़ा है। धन्यवाद!
मार्वेंटस

मैंने एक excludeतर्क भी पारित करने के बारे में सोचा , लेकिन, wp_list_pagesकई अन्य WP फ़ंक्शनों के विपरीत , wp_nav_menuइसमें एक भी शामिल नहीं है। इसलिए, भले ही मैं मेनू या वॉकर में कॉल करते समय एक निर्दिष्ट करता हूं, यह अंदर नहीं उठाया wp_nav_menuजाएगा, क्या यह होगा?
Marventus

क्षमा करें, सीधे नहीं सोच रहा था जब मैंने लिखा था कि, तुरंत हटा दिया गया।
आत्मासेकाह

इसके बारे में चिंता मत करो!
Marventus

जवाबों:


26

विधि 1

आप कुछ अतिरिक्त बहिष्करण तर्क संग्रहीत करने के लिए अपने कस्टम वॉकर में एक निर्माता जोड़ सकते हैं, जैसे:

class custom_nav_walker extends Walker_Nav_Menu {
    function __construct( $exclude = null ) {
        $this->exclude = $exclude;
    }

    function skip( $item ) {
        return in_array($item->ID, (array)$this->exclude);
        // or
        return in_array($item->title, (array)$this->exclude);
        // etc.
    }

    // ...inside start_el, end_el
    if ( $this->skip( $item ) ) return;
}

या निर्माणकर्ता को छोड़ दें और $excludeइसे wp_nav_menu()पसंद करने के लिए वॉकर के रूप में पारित करने से पहले अपनी संपत्ति निर्धारित करें:

$my_custom_nav_walker = new custom_nav_walker;
$my_custom_nav_walker->exclude = array( ... );

आप जिस चीज़ को छोड़ रहे हैं, उसके आधार पर, सही फ़ॉर्म को बहिष्कृत करें।

विधि 2

यह आप wp_get_nav_menu_itemsफ़िल्टर में हुक करके ऐसा कैसे करेंगे ।

function wpse31748_exclude_menu_items( $items, $menu, $args ) {
    // Iterate over the items to search and destroy
    foreach ( $items as $key => $item ) {
        if ( $item->object_id == 168 ) unset( $items[$key] );
    }

    return $items;
}

add_filter( 'wp_get_nav_menu_items', 'wpse31748_exclude_menu_items', null, 3 );

नोट: object_idमेनू बिंदु के लिए वस्तु है, जबकि IDमेनू आईडी है, ये अलग हैं।

मुझे अपने विचारों को जानने दें।


धन्यवाद! वह काम कर सकता है। मैं इसे एक कोशिश करूँगा और आपको बता दूंगा।
Marventus

मैंने कॉन्स्ट्रक्टर के दृष्टिकोण की कोशिश की और, मैं चाहे जो भी कोशिश करूं, मुझे in_arrayफ़ंक्शन के लिए "गलत तर्क के लिए दूसरा तर्क" त्रुटि मिलती रही है । क्या मुझसे कुछ ग़लत हो रहा है?
मार्वेंटस

$excludeसंपत्ति श्रेणी होनी चाहिए। इसलिए सुनिश्चित करें कि आप कंस्ट्रक्टर में एक सरणी पास कर रहे हैं, या मेरे उत्तर में अपडेटेड कोड देखें। विशेष रूप से टाइपकास्ट $this->exclude, बस के मामले में एक सरणी पारित नहीं किया है।
आत्मासेकाह

इस बारे में क्षमा करें: मेरे पास मेरे फ़ंक्शन में एक टाइपो था। मैंने बस कोशिश की $exclude = array ('4', '7');और स्लग का उपयोग भी किया, लेकिन इसका वॉकर आउटपुट पर कोई प्रभाव नहीं पड़ रहा है। मैं दूसरा तरीका आजमाऊंगा और आपको बता दूंगा।
Marventus

नहीं, यह भी काम नहीं किया। मुझे लगता है कि मैं यह जानने की कोशिश कर रहा हूं कि मेरा दिमाग
खराब है

0

क्या यह मदद करता है

$exclude_array = ( $args->exclude ) ? explode(',', $args->exclude) : array();
$args->exclude = implode( ',', apply_filters('wp_nav_menu_excludes', $exclude_array) );

उदाहरण के तौर पे

< ?php wp_nav_menu( array( 'container_class' => 'menu-header', 'theme_location' => 'primary', 'exclude' => '66' ) ); ?>

हाय सैक, मैं यह उल्लेख करना भूल गया कि जो समाधान काम नहीं करता था, उनमें से एक कस्टम नेवमेनू फ़ंक्शन बनाने और फ़ंक्शन की चूक के लिए अतिरिक्त तर्क के रूप में उस कोड को जोड़ना था। अफसोस की बात है, यह काम नहीं किया। मैंने इसे वॉकर में शामिल करने की कोशिश नहीं की, लेकिन मुझे नहीं लगता कि मैं या तो उसी कारण से काम करूंगा, जिसका मैंने ऊपर उल्लेख किया है, मुख्य रूप से यह wp_nav_menu"बहिष्कृत" तर्क नहीं है, लेकिन मैं गलत हो सकता है।
Marventus

मैंने स्पष्टता के लिए इसे शामिल करने के लिए अपने मूल पोस्ट को अपडेट किया।
मार्वेंटस

क्या होगा यदि आप एक कस्टम वॉकर का उपयोग नहीं करते हैं, इसके बजाय आप एक नियमित रूप से nav_menu का उपयोग करते हैं और अपनी कस्टम छवि के साथ wp_get_nav_menu_items () के साथ आइटम निकालें
saq

यह सामान्य रूप से एक अच्छा समाधान होगा, लेकिन इस विशेष मामले में, wp_get_nav_menu_itemsछवियों को पुनर्प्राप्त नहीं करेंगे क्योंकि img टैग वास्तविक कस्टम मेनू में संग्रहीत नहीं हैं (केवल उनके फ़ाइल नाम विवरण क्षेत्र में हैं, उदाहरण के लिए, "image1.png" )। कस्टम वॉकर वह है जो मुझे मेनू आउटपुट में img टैग सम्मिलित करने की अनुमति देता है।
मार्वेंटस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.