Galat “Mencoba mendapatkan properti non-objek” dengan Custom Walker untuk wp_nav_menu

8

Saya mencoba menambahkan beberapa hal terkait ARIA ke fungsi wp_nav_menu. Saya menggunakan kelas walker khusus untuk tujuan ini:

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

Saya hanya menyalin-paste kelas Walker_Nav_Menu asli dan menambahkan hal-hal, tetapi saya mendapatkan kesalahan karena variabel $ args diperlakukan seperti objek benar-benar sebuah array. Tetapi hal yang sangat aneh adalah kesalahan ini tetap ada, bahkan jika saya meneruskan walker asli seperti ini:

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

Ini adalah pesan kesalahan yang saya dapatkan:

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

Garis-garisnya terlihat seperti ini (Dalam file asli!):

(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
sumber
Apakah Anda mendapatkan kesalahan jika tidak melewati walker sama sekali? Argumen harus menjadi objek, saya pikir itulah yang dikatakan inline docs dan apa yang wp_nav_menu()lolos.
Jarang
Tidak, jika saya hanya menggunakan wp_nav_menu()fungsi default tanpa alat bantu jalan, itu berfungsi dengan baik. Ya, tapi mengapa itu array? Saya bahkan var_dumpmenyuntingnya, tidak ada objek.
Rudolf
Saya tidak yakin apa yang sedang terjadi, karena passing new Walker_Nav_Menuharus berperilaku identik dengan tidak melewati walker. Apakah ada hal lain yang terjadi, plugin yang menghubungkan / memanipulasi fungsi menu?
Jarang
Saya baru saja melakukan beberapa pengujian tambahan, dan saya yakin ini adalah bug WordPress. Dalam kasus saya, menu nav yang saya gunakan tidak ditugaskan di backend. Oleh karena itu halaman daftar mundur digunakan, maka variabel args adalah array. Saya akan melacak ini ke sumber sekarang, kemudian memberi tahu Anda apa yang saya temukan.
Rudolf
Jika saya menetapkan menu dengan benar, itu berfungsi!
Rudolf

Jawaban:

18

Saya mendapatkan kesalahan ini ketika tidak ada menu yang ditentukan atau tidak ada menu yang ditetapkan untuk lokasi di Appearance->Menus. Ketika itu terjadi wp_nav_menugunakan mundur halaman walker.

  1. The fallback (default) untukwp_nav_menu yaituwp_walker_page
  2. yang menggunakan wp_page_menu
  3. yang menggunakan wp_list_pages
  4. yang menggunakan walk_page_tree
  5. yang menggunakan Walker_Pagetidak Walker_Nav_Menu.

Dan ternyata kedua walker itu tidak kompatibel. Saya tidak tahu mengapa itu tidak gagal dengan anggun. Bagi saya itu seperti bug.

Dengan set menu di wp-admin->Appearance->Menus, kode Anda berfungsi.

Anda dapat menghindari kesalahan dengan memeriksa untuk melihat bahwa ada menu yang ditetapkan ke lokasi sebelum mencoba menggunakan lokasi.

$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,
  ) );
}

Atau, jika Anda lebih suka kode tambahan antihistamin (terima kasih @Rarst):

if (has_nav_menu('primary')) {
  wp_nav_menu( array(
      'theme_location' => 'primary',
      'walker'         => new Walker_Nav_Menu_With_Aria,
  ) );
}
s_ha_dum
sumber
Fallback hanya digunakan ketika semuanya gagal menampilkan halaman. Jika menu berfungsi dengan baik, item akan berjalan sesuai dengan walk_nav_menu_tree()yang digunakan Walker_Nav_Menusecara default.
Jarang
Pembaruan yang bagus! Tidak terpikir oleh saya fungsi yang salah mungkin meraih walker (itu meh). Juga ada has_nav_menu()cek itu.
Jarang
Itulah yang ingin saya posting: D Menu nav $argsdikonversi menjadi objek wp-includes/nav-menu-template.phppada baris 145 oleh wp_nav_menu()fungsi. The wp_page_menu()Fungsi yang digunakan sebagai fallback tidak melakukan itu, tapi malah melewati array ke Walker dari menu nav yang membutuhkan objek. Jika Anda baru saja menambahkan a $args = (object) $argsdi atas start_elfungsi kelas Walker, Anda dapat memperbaikinya. Di mana tempat yang tepat untuk melaporkan ini ke tim WordPress?
Rudolf
@Rudolf core bugs harus dilaporkan di core.trac.wordpress.org
Rarst
The WP_Postobjek yang dilewatkan sebagai $itemberbeda, juga (Karena ini, halaman tidak memiliki nama dan daftar hanya terdiri dari kosong <li>elemen). Diperlukan beberapa refactoring serius untuk membuat kedua alat bantu ini kompatibel.
Rudolf
0

gunakan kode di bawah ini untuk memperbaiki:

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
sumber