it-swarm.com.de

Schließen Sie Menüelemente dynamisch aus wp_nav_menu aus

Ich habe nach Informationen zum Ausschließen/Entfernen von Navigationsmenüelementen aus benutzerdefinierten Menüs gesucht, und der einzige gefundene Thread hatte keine für mich nützlichen Antworten.

1. Hintergrund:

Ich habe ein Dock-Menü mit WP benutzerdefinierten Menüs (wp_nav_menu) und jqDock auf meiner Site zusammengestellt. Da jqDock fortlaufende Bilder oder Bildverknüpfungen benötigt, um seine Magie zu entfalten, benutze ich einen benutzerdefinierten Walker, damit die HTML-Ausgabe des Navigationsmenüs so aussieht:

<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>

Der Code für meinen benutzerdefinierten Walker lautet:

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 .= "";
    }

}

Das jqDock-Skript erkennt dann die Menü-ID ('menu-first') und ersetzt die Ausgabe von wp_nav_menu durch die Ausgabe des Dock-Menüs. Die HTML-Ausgabe des Dock-Menüs ändert sich basierend auf den Optionen, die beim Laden von jqDock angegeben wurden.

2. Die Frage:

Ich möchte bestimmte Menüelemente nicht anzeigen (d. H. Ausschließen), je nachdem, wo sich der Benutzer auf der Site befindet. Zum Beispiel möchte ich das Startelement nur anzeigen, wenn sich der Benutzer nicht in der Startseite befindet, und das Element "Zufälliger Beitrag" nur, wenn er sich in der Startseite befindet.

3. Verworfene Lösungen:

a. Mehrere Menüs: Das Registrieren und Erstellen mehrerer Menüs und der anschließende bedingte Aufruf können funktionieren. Ich denke jedoch, dass dies aus vielen Gründen überhaupt keine ideale oder saubere Lösung ist. Außerdem sind mehrere Menüs nicht einfach zu warten oder zu aktualisieren.

b. Regex Search and Replace: Dies könnte mich zwingen, den Parameter needle jedes Mal zu ändern, wenn ich die jqDock-Optionen ändere, weil die HTML-Ausgabe geändert wird.

c. CSS 'display' property: Das Ausblenden der Elemente über die CSS-Anzeigeeigenschaft funktioniert, da es jedoch auf die Ausgabe des jqDock-Menüs angewendet werden muss, wirkt es sich auf die visuelle Darstellung des Menüs aus.

4. Fehlgeschlagene Lösungen:

a. Filtern nach wp_nav_menu_items: Ich habe versucht, die Variable '$ items' (Zeichenfolge) abzufangen und ihr verschiedene Werte über bedingte Tags mit folgendem Code zuzuweisen:

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');

Dies funktioniert nur teilweise, da sich die Menüelemente zwar ändern, die bedingten Tags jedoch ignoriert werden. Ich denke, dies ist sinnvoll, da der Filter in dem Moment angewendet wird.

b. Benutzerdefinierte Navigationsmenüfunktion: Ich habe versucht, eine eigene benutzerdefinierte Navigationsmenüfunktion zu erstellen, um dem Array $ defaults ein Ausschlussargument hinzuzufügen und diesen leicht geänderten Code aus wp_list_pages zum Auffüllen des zusätzlichen Arguments zu verwenden:

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

Irgendwelche Ideen?

16
Marventus

Methode 1

Sie können Ihrem benutzerdefinierten Walker einen Konstruktor hinzufügen, um einige zusätzliche Ausschlussargumente zu speichern, z.

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;
}

Oder löschen Sie den Konstruktor und setzen Sie die Eigenschaft $exclude, bevor Sie ihn als Walker an wp_nav_menu() übergeben:

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

Geben Sie, je nachdem, durch was Sie ausschließen, das richtige Formular für den Ausschluss an.

Methode 2

So würden Sie vorgehen, indem Sie sich in den wp_get_nav_menu_items-Filter einhängen.

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 );

Hinweis: object_id ist das Objekt, auf das das Menü zeigt, während ID die Menü-ID ist. Diese sind jedoch unterschiedlich.

Lass mich wissen was du denkst.

25
soulseekah

hilft das

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

als Beispiel

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