wp_nav_menuのカスタムウォーカーでエラー「非オブジェクトのプロパティを取得しようとしています」


8

私はいくつかのARIA関連のものをwp_nav_menu関数に追加しようとしています。この目的でカスタムウォーカークラスを使用します。

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

元のWalker_Nav_Menuクラスをコピーアンドペーストして追加しただけですが、オブジェクトのように扱われる$ args変数は実際には配列であるため、エラーが発生します。しかし、本当に奇妙なのは、次のように元のウォーカーを渡しても、このエラーが続くことです。

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

これらは私が得るエラーメッセージです:

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

行は次のようになります(元のファイルでは!):

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

ウォーカーをまったく渡さないとエラーが発生しますか?議論客観的であるべきです、それはインラインドキュメントが言うことであり、wp_nav_menu()通過することだと思います。
Rarst

いいえ、デフォルトのwp_nav_menu()関数をウォーカーなしで使用すると、完全に機能します。ええ、でもなぜそれが配列なのですか?私もvar_dumpそれを食べました、オブジェクトはありません。
ルドルフ

そのとき何が起こっているのか私にはnew Walker_Nav_Menuわかりません。メニュー機能にフック/操作するプラグインは他にありますか?
Rarst

追加のテストをいくつか行ったところ、WordPressのバグであると確信しています。私の場合、使用したナビゲーションメニューがバックエンドに割り当てられていません。そのため、リストページのフォールバックが使用されましたが、args変数は配列のようです。これをソースまでたどって、見つけたものを教えます。
ルドルフ

メニューを正しく割り当てると、機能します!
ルドルフ

回答:


18

メニューが定義されていない場合、またはの場所に設定されているメニューがない場合に、このエラーが発生しAppearance->Menusます。その場合wp_nav_menuは、ページウォーカーフォールバックを使用します。

  1. フォールバック(デフォルト)wp_nav_menuwp_walker_page
  2. 使用する wp_page_menu
  3. 使用する wp_list_pages
  4. 使用する walk_page_tree
  5. 使用しWalker_PageないWalker_Nav_Menu

そしてどうやら2つの歩行者は互換性がありません。なぜうまくいかないのかわかりません。それは私にはバグのようです。

メニューをに設定するwp-admin->Appearance->Menusと、コードが機能します。

この場所を使用する前に、その場所にメニューが割り当てられていることを確認することで、エラーを回避できます。

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

または、アンチヒスタミンの追加コードを少なくしたい場合(@Rarstに感謝):

if (has_nav_menu('primary')) {
  wp_nav_menu( array(
      'theme_location' => 'primary',
      'walker'         => new Walker_Nav_Menu_With_Aria,
  ) );
}

フォールバックは、他のすべてがページの表示に失敗した場合にのみ使用されます。メニューが適切walk_nav_menu_tree()に機能する場合Walker_Nav_Menu、デフォルトで使用される項目が使用されます。
Rarst

素敵なアップデート!誤った機能が私に発生しなかったのは、歩行者をつかんでいる可能性があります(それは私です)。has_nav_menu()そのチェックのためにもあります。
Rarst

それがまさに私が投稿したかったことです:Dナビゲーションメニュー$argswp-includes/nav-menu-template.phpwp_nav_menu()関数によって145行目のオブジェクトに変換されます。wp_page_menu()フォールバックとして使用されている機能は、それを行うが、その代わりに、単にオブジェクトを必要とするナビゲーションメニューからウォーカーの配列を渡していません。Walkerクラスの関数の$args = (object) $args先頭にa を追加するだけで、start_elこれを修正できます。これをWordPressチームに報告する適切な場所はどこですか?
ルドルフ

@Rudolfコアのバグはで報告しなければならないcore.trac.wordpress.org
Rarst

WP_Post渡されるオブジェクト$item異なっている、あまりにも(このため、ページが何の名前を持っていないとリストがちょうど空から構成<li>要素)。これら2つのウォーカーに互換性を持たせるには、いくつかの深刻なリファクタリングが必要になります。
ルドルフ

0

以下のコードを使用して修復します。

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;
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.