Fehler "Versuch, die Eigenschaft eines Nichtobjekts abzurufen" mit Custom Walker für wp_nav_menu

8

Ich versuche, der Funktion wp_nav_menu einige ARIA-bezogene Dinge hinzuzufügen. Zu diesem Zweck verwende ich eine benutzerdefinierte Walker-Klasse:

class Walker_Nav_Menu_With_Aria extends Walker_Nav_Menu {
        function start_lvl( &$output, $depth = 0, $args = array() ) {
                $indent = str_repeat("\t", $depth);
                $output .= "\n$indent<ul class=\"sub-menu\" role=\"group\">\n";
        }

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

        function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
                $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_names ? ' class="' . esc_attr( $class_names ) . '"' : '';

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

                // Add attributes for <li>
                $li_attributes  = ' role="treeitem"';
                $li_attributes .= ' aria-expanded="false"';

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

                $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        ) .'"' : '';

                // Add attributes for <a>
                $attributes .= $depth == 0 ? ' tabindex="0"' : ' tabindex="-1"';

                $item_output = $args->before;
                $item_output .= '<a'. $attributes .'>';
                $item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $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 = 0, $args = array() ) {
                $output .= "</li>\n";
        }
}

Ich habe gerade die ursprüngliche Walker_Nav_Menu-Klasse kopiert und hinzugefügt, aber es werden Fehler angezeigt, da die Variable $ args, die wie ein Objekt behandelt wird, wirklich ein Array ist. Aber das wirklich Seltsame ist, dass dieser Fehler weiterhin besteht, selbst wenn ich den ursprünglichen Walker wie folgt übergebe:

wp_nav_menu( array(
    'theme_location' => 'main-nav',
    'walker'         => new Walker_Nav_Menu,
) );

Dies sind die Fehlermeldungen, die ich erhalte:

NOTICE: TRYING TO GET PROPERTY OF NON-OBJECT IN /USERS/RUDOLF/SITES/LOCALHOST/WP/WP-INCLUDES/NAV-MENU-TEMPLATE.PHP ON LINE 88
NOTICE: TRYING TO GET PROPERTY OF NON-OBJECT IN /USERS/RUDOLF/SITES/LOCALHOST/WP/WP-INCLUDES/NAV-MENU-TEMPLATE.PHP ON LINE 90
NOTICE: TRYING TO GET PROPERTY OF NON-OBJECT IN /USERS/RUDOLF/SITES/LOCALHOST/WP/WP-INCLUDES/NAV-MENU-TEMPLATE.PHP ON LINE 90
NOTICE: TRYING TO GET PROPERTY OF NON-OBJECT IN /USERS/RUDOLF/SITES/LOCALHOST/WP/WP-INCLUDES/NAV-MENU-TEMPLATE.PHP ON LINE 92

Die Zeilen sehen folgendermaßen aus (In der Originaldatei!):

(88) $item_output = $args->before;
(89) $item_output .= '<a'. $attributes .'>';
(90) $item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
(91) $item_output .= '</a>';
(92) $item_output .= $args->after;
Rudolf
quelle
Erhalten Sie eine Fehlermeldung, wenn Sie überhaupt nicht am Walker vorbeikommen? Argumente sollten objektiv sein, ich denke, das ist es, was Inline-Dokumente sagen und was wp_nav_menu()passiert.
Rarst
Nein, wenn ich nur die Standardfunktion wp_nav_menu()ohne Gehhilfe verwende, funktioniert sie perfekt. Ja, aber warum ist es dann ein Array? Ich habe es sogar var_dumpbearbeitet, kein Objekt.
Rudolf
Ich bin mir nicht sicher, was dann los ist, denn das Passieren new Walker_Nav_Menusollte sich genauso verhalten wie das Nicht-Passieren des Walkers. Ist noch etwas los, irgendwelche Plugins, die sich in die Menüfunktion einbinden / diese manipulieren?
Rarst
Ich habe gerade einige zusätzliche Tests durchgeführt und bin mir sicher, dass dies ein WordPress-Fehler ist. In meinem Fall wurde das von mir verwendete Navigationsmenü nicht im Backend zugewiesen. Daher wurde das Listback der Listenseiten verwendet. Es scheint, dass die Variable args ein Array ist. Ich werde dies jetzt bis zur Quelle zurückverfolgen und Ihnen dann sagen, was ich gefunden habe.
Rudolf
Wenn ich ein Menü richtig zuordne, funktioniert es!
Rudolf

Antworten:

18

Ich erhalte diese Fehlermeldung, wenn für den Standort unter keine Menüs definiert oder keine Menüs festgelegt sind Appearance->Menus. In diesem Fall wp_nav_menuwird ein Page Walker-Fallback verwendet.

  1. Der Fallback (Standard) fürwp_nav_menu istwp_walker_page
  2. welche verwendet wp_page_menu
  3. welche verwendet wp_list_pages
  4. welche verwendet walk_page_tree
  5. das nutzt Walker_Pagenicht Walker_Nav_Menu.

Und anscheinend sind die beiden Wanderer nicht kompatibel. Ich weiß nicht, warum es nicht anmutig scheitert. Das scheint mir ein Fehler zu sein.

Wenn ein Menü auf eingestellt ist wp-admin->Appearance->Menus, funktioniert Ihr Code.

Sie können den Fehler vermeiden, indem Sie überprüfen, ob dem Standort ein Menü zugewiesen ist, bevor Sie versuchen, den Standort zu verwenden.

$locations = get_nav_menu_locations();
if (0 !== $locations['main-nav']) {
  wp_nav_menu( array(
      'theme_location' => 'main-nav',
      'walker'         => new Walker_Nav_Menu_With_Aria,
  ) );
}

Oder wenn Sie weniger Antihistamin-Code bevorzugen (danke @Rarst):

if (has_nav_menu('primary')) {
  wp_nav_menu( array(
      'theme_location' => 'primary',
      'walker'         => new Walker_Nav_Menu_With_Aria,
  ) );
}
s_ha_dum
quelle
Fallback wird nur verwendet, wenn alle anderen Seiten nicht angezeigt werden. Wenn das Menü ordnungsgemäß funktioniert, werden Elemente ausgeführt, walk_nav_menu_tree()die Walker_Nav_Menustandardmäßig verwendet werden.
Rarst
Schönes Update! Mir ist nicht in den Sinn gekommen, dass eine falsche Funktion darin besteht, den Walker zu greifen (das ist meh). Auch gibt es has_nav_menu()für diesen Scheck.
Rarst
Genau das wollte ich gerade posten: D Das Navigationsmenü wird von der Funktion $argsin wp-includes/nav-menu-template.phpZeile 145 in ein Objekt konvertiert wp_nav_menu(). Die wp_page_menu()Funktion, die als Fallback verwendet wird, tut dies nicht, sondern übergibt das Array einfach über das Navigationsmenü, das das Objekt benötigt, an den Walker. Wenn Sie $args = (object) $argsoben in der start_elFunktion der Walker-Klasse nur ein hinzufügen , können Sie dies beheben. Wo wäre der richtige Ort, um dies dem WordPress-Team zu melden?
Rudolf
@ Rudolf Core Bugs sollten unter core.trac.wordpress.org
Rarst
Das übergebene WP_PostObjekt $itemist ebenfalls unterschiedlich (Aus diesem Grund haben die Seiten keine Namen und die Liste besteht nur aus leeren <li>Elementen). Einige ernsthafte Umgestaltungen wären erforderlich, um diese beiden Wanderer kompatibel zu machen.
Rudolf
0

Verwenden Sie den folgenden Code zur Reparatur:

add_filter( 'wp_get_nav_menu_object', 'override_wp_get_nav_menu_object', 10, 2 );
function override_wp_get_nav_menu_object( $menu_obj, $menu ) {

    if ( ! is_object( $menu_obj ) ) {
        $menu_obj = (object) array( 'name' => '' );
    }

    return $menu_obj;
}
hannanstd
quelle