web-dev-qa-db-ja.com

ワードプレスのカスタムメニューウォーカーでリクラス名を変更する

メインのLIとネストされたLIに適用されるクラスを持つナビゲーションを作成しています。例:

<ul>
<li class="className">Test</li>
<li class="className">Test
    <ul>
        <li class="ADifferentclassName">test</li>
        <li class="ADifferentclassName">test</li>
    </ul>
</li>
</ul>

私はULとすべてのLIのクラスを取得する方法を考え出しましたが、ネストされたLIのクラスを取得する方法を理解することができます。

これが私のカスタムウォーカーです。

これはネストULクラスを変更します

 class My_Walker_Nav_Menu extends Walker_Nav_Menu {
  function start_lvl(&$output, $depth) {
    $indent = str_repeat("\t", $depth);
    $output .= "\n$indent<ul class=\"nav-main-sub-list\">\n";
  }

これにより、余分なワードプレスクラスがすべて削除され、クラスnav-main-itemがすべてのliのクラスに追加されます。

    public function start_el( &$output, $item, $depth, $args )
    {

        $attributes  = '';

        ! empty ( $item->attr_title )
            // Avoid redundant titles
            and $item->attr_title !== $item->title
            and $attributes .= ' title="' . esc_attr( $item->attr_title ) .'"';

        ! empty ( $item->url )
            and $attributes .= ' href="' . esc_attr( $item->url ) .'"';

        $attributes  = trim( $attributes );
        $title       = apply_filters( 'the_title', $item->title, $item->ID );
        $item_output = "$args->before<a $attributes>$args->link_before$title</a>"
                        . "$args->link_after$args->after";

        // Since $output is called by reference we don't need to return anything.


        $output .= $indent . '<li class="nav-main-item">';

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

}

入れ子になったLIのクラスを変更する方法がわからない。私は何もしませんでした。任意のヒント?

1
Steph Gill

トラブルシューティング

WP_DEBUGwp-config.php定数を有効にすると、次のエラーが公開されました。

-関数シグネチャ

厳格な標準が有効になっている場合、互換性のないメソッドシグネチャの詳細を示すエラーが表示されます。絶対に必要というわけではありませんが、できるだけ多くのエラーを排除したいです。これを修正するには、新しいWalker_Nav_Menuクラスのstart_el()およびstart_lvl()メソッドの宣言が一致する必要があります Walker_Nav_Menuクラス自体のもの あらゆる種類のパラメーター/引数関連のエラーをスローすることなく、Walker_Nav_Menuクラスのドロップイン置換として機能できます。

この:

class Wpse_145991_Walker_Nav_Menu extends Walker_Nav_Menu {
    function start_lvl( &$output, $depth ) {
        //...
    }

    public function start_el( &$output, $item, $depth, $args ) {
        //...
    }
}

これになるはずです:

class Wpse_145991_Walker_Nav_Menu extends Walker_Nav_Menu {
    function start_lvl( &$output, $depth = 0, $args = array() ) {
        //...
    }

    function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
        //...
    }
}

-Notice: Undefined variable: indent

新しいクラスのstart_el()メソッドの下部近くに、次の行が表示されます。

$output .= $indent . '<li class="nav-main-item">';

ただし、$indentはメソッド内で定義されることはありません。 Walkerクラスは、HTMLホワイトスペースを$indentタブ文字の数にフォーマットするために$depth変数を設定する傾向があります。機能的には関係ありませんが、前述の行の前のどこかに$indentを定義することで修正できます。

$indent = str_repeat("\t", $depth);

この時点で、質問に投稿された実装は、エラーや警告をスローすることなくメニューを生成するはずです。


深さごとに異なるクラスを指定する

理論

Walker_Nav_Menuwalk()ingの場合、start_el()メソッドとstart_lvl()メソッドの両方に$depth引数が渡されます。この引数は、「レベル、」「サブメニュー」、または現在のアイテムとデータルート間の<ul>要素(最上位の<ul>要素)。

Walker_Nav_Menu $depth Parameter

実装

この$depthに基づいて条件分岐することにより、さまざまな要素とレベルにさまざまなクラスを割り当てることができます。たとえば、switchを使用すると、各アイテムとレベルのクラスを微調整できます。

class Wpse_145991_Walker_Nav_Menu extends Walker_Nav_Menu {
    function start_lvl( &$output, $depth = 0, $args = array() ) {
        $indent = str_repeat( "\t", $depth );

        // Select a CSS class for this `<ul>` based on $depth
        switch( $depth ) {
            case 0:
                // Top-level submenus get the 'nav-main-sub-list' class
                $class = 'nav-main-sub-list';
                break;
            case 1:
            case 2:
            case 3:
                // Submenus nested 1-3 levels deep get the 'nav-other-sub-list' class
                $class = 'nav-other-sub-list';
                break;
            default:
                // All other submenu `<ul>`s receive no class
                break;
        }

        // Only print out the 'class' attribute if a class has been assigned
        if( isset( $class ) )
            $output .= "\n$indent<ul class=\"$class\">\n";
        else
            $output .= "\n$indent<ul>\n";
    }

    function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
        $indent = str_repeat("\t", $depth);
        $attributes  = '';

        ! empty ( $item->attr_title )
        // Avoid redundant titles
        and $item->attr_title !== $item->title
        and $attributes .= ' title="' . esc_attr( $item->attr_title ) .'"';

        ! empty ( $item->url )
        and $attributes .= ' href="' . esc_attr( $item->url ) .'"';

        $attributes  = trim( $attributes );
        $title       = apply_filters( 'the_title', $item->title, $item->ID );
        $item_output = "$args->before<a $attributes>$args->link_before$title</a>"
                       . "$args->link_after$args->after";

        // Select a CSS class for this `<li>` based on $depth
        switch( $depth ) {
            case 0:
                // Top-level `<li>`s get the 'nav-main-item' class
                $class = 'nav-main-item';
                break;
            default:
                // All other `<li>`s receive no class
                break;
        }

        // Only print out the 'class' attribute if a class has been assigned
        if( isset( $class ) )
            $output .= $indent . '<li class="'. $class . '">';
        else
            $output .= $indent '<li>';

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