WordPressウォーカークラスに精通する

公開: 2020-11-27

ウォーカークラスに慣れていない場合は、それがあなたの仕事にどれほど役立つかを驚​​かせる準備をしてください。 WordPressWalkerクラスはWordPress2.1に実装され、開発者がHTMLをレンダリングする目的でツリーのようなデータ構造をトラバースする手段を提供します。 この記事では、ウォーカーパラメータがどのように機能するか、およびメニュー、カテゴリ、コメントの出力をカスタマイズする方法について学習します。

さあ行こう!

ウォーカークラスの概要

WordPressでは、ナビゲーションメニュー、カテゴリリスト、コメントリストなどの階層構造を持つオブジェクトがよく見られます。

ご存知かもしれませんが、ツリーデータ構造の場合、一部の要素は親であり、他の要素はその子です。 「投稿サブカテゴリ1」は「投稿カテゴリ1」の子であり、コメントへの返信はコメント自体の子コメントであり、「サービス1」は「サービス」項目の子メニュー項目です。

Walkerは、各オブジェクトまたは連想配列を単に「ウォーク」し、各ノードで関数を実行するという名前が付けられています。 これで達成したいのは、特定の要件に応じてさまざまな方法で「トップレベル」のリンクとその「子」アイテムを一覧表示する機能です。

つまり、WordPressは標準の<ul> <li>構造を提供し、引数をカスタマイズできますが、Walkerを拡張することで、HTMLコンテンツを変更して構造自体をカスタマイズできます。

Walkerクラスに関連するコアファイルはwp-includes/class-wp-walker.phpであり、これまでにリストしたすべてのタイプのツリーのようなデータを管理します。

これは抽象PHPクラスであるため、HTMLを生成するには、そのプロパティとメソッドのカスタマイズされたバージョンを定義する開発者が拡張する必要があります。 それでは、 class-wp-walker.phpファイルの子クラスを1つずつ調べてみましょう。

子クラス

$tree_typeは、1つの型または型の配列で提供され、クラスが処理する内容を定義するオプションの変数です。

 public $tree_type = array( 'post_type', 'taxonomy', 'custom' );

$db_fieldsは必須の変数であり、使用するデータベースフィールドを定義します。 このプロパティは、「parent」と「id」の2つのキーを持つ配列であり、その値は、それぞれ親IDとアイテムIDを保持するオブジェクトプロパティの名前です。

 public $db_fields = array( 'parent' => 'menu_item_parent', 'id' => 'db_id', );

$max_pagesプロパティもオプションであり、その役割は、ページ付きウォーカーが歩く最大ページ数を指定することです。

 public $max_pages = 1;

$has_childrenは実際には自明であり、現在の要素に子があるかどうかに応じてtrueまたはfalseの値を持ちます。

 public $has_children;

start_lvlメソッドは、新しいツリーのようなオブジェクトのルートで実行され、$ output、$ depth、および$args引数を取ります。

 public function start_lvl( &$output, $depth = 0, $args = array() ) {}

$output引数は追加のコンテンツを追加し、 $depthはアイテムの深さを指定します。 $argsは追加の引数の配列です。

end_lvlメソッドは、start_lvlメソッドによって以前に開かれたタグをすべて閉じます。

 public function end_lvl( &$output, $depth = 0, $args = array() ) {}

start_el (Start Element)メソッドは、現在の要素の開始HTMLタグを表示するために使用されます。 たとえば、メニューの場合、通常は<li>タグです。

 public function start_el( &$output, $object, $depth = 0, $args = array(), $current_object_id = 0 ) {}

end_el関数は、Walkerがすべての子を持つ要素を渡し、終了タグを返した後に呼び出されます。

 public function end_el( &$output, $object, $depth = 0, $args = array() ) {}

display_elementは、実際にはツリーオブジェクトの要素を表示します。 start_elstart_lvldisplay_elementend_lvlend_el関数をこの順序で呼び出します。 それでは、その議論を見てみましょう。

  • $ element :現在の要素
  • $ children_elements :ツリーオブジェクトのすべての子要素
  • $ max_depth :探索できる最大深度制限
  • $ depth :現在のレベル
  • $ args :追加のオプションの引数
  • $ output :現在のHTML出力。

次に、Twenty TwentyテーマをアクティブにしたWordPressインストールを使用して、データ型ごとに1つの例を示します。

メニュー構造のカスタマイズ

WordPressがメニューを表示するために使用するwp_nav_menu()関数は、 wp-includes/nav-menu-template.phpファイルに含まれています。 このファイルでは、WordPressは605行目あたりのWalker_Nav_Menuクラスも呼び出しています。

 function walk_nav_menu_tree( $items, $depth, $r ) { $walker = ( empty( $r->walker ) ) ? new Walker_Nav_Menu : $r->walker; return $walker->walk( $items, $depth, $r ); }

Walker_Nav_Menuクラスは、 wp-includes/class-walker-nav-menu.phpファイル内で定義され、基本的にすべてのファイルのコンテンツです。

メニューの出力を表示するために、WordPressコードはこのファイル内に記述されているWalker_Nav_Menuクラスのプロパティとメソッドを使用します。

たとえば、多くの開発者が直面するよく知られた問題を修正しましょう。これは、訪問者がクリックできないように、親メニュー項目の要素を空のカスタムリンク(「#」)で変更することです。

結果を比較できるようにするために、最初に、 <header>要素の開始直後にheader.phpに以下のコードを追加することにより、プライマリメニューのクローンを作成します。

 <header class="header-footer-group" role="banner"> <?php wp_nav_menu( array( 'menu_class' => 'primary-menu reset-list-style' ) ); ?>

ここで実際に行ったことは、プライマリメニューを再生成し、そのクラスprimary-menu reset-list-styleを新しいメニューにも追加することで、ドロップダウン機能とCSSを継承することでした。

次に、 functions.phpファイルに、Walker_Nav_Menuクラスを拡張するクラスを作成します。 要素のタイプを変更したいので、 start_elメソッドをオーバーライドします。

 if ( !class_exists('My_Custom_Nav_Walker') ) { class My_Custom_Nav_Walker extends Walker_Nav_Menu { function start_el(&$output, $item, $depth=0, $args=[], $id=0) { $output .= "<li class='" . implode(" ", $item->classes) . "'>"; if ($item->url && $item->url != '#') { $output .= '<a href="' . $item->url . '">'; } else { $output .= '<span>'; } $output .= $item->title; if ($item->url && $item->url != '#') { $output .= '</a>'; } else { $output .= '</span>'; } } } }

したがって、通常は各要素を<li>タグでラップし、次に、リンクが「#」の場合はifステートメントを使用してスパンを追加し、残りは<a>タグを使用します。

これをメニューに適用するには、前に追加したメニューコードに戻り、ウォーカーパラメーターを指定します。

 wp_nav_menu( array( 'walker' => new My_Custom_Nav_Walker, 'menu_class' => 'primary-menu reset-list-style' ) );

これで、結果は次のようになります。

メニュー項目の「サービス」にカーソルを合わせると、ハンドカーソルは表示されず、このメニュー項目をクリックすることもできません。 ただし、ドロップダウンサブメニューは引き続き正しく表示されます。

カテゴリのカスタマイズ

まず、管理領域に移動し、いくつかの投稿カテゴリとサブカテゴリを作成して、デモンストレーション用のカテゴリツリーを作成します。

その後、 header.phpのどこかにこのコードを追加して、カテゴリリストを生成します。 以前のように、ヘッダー要素の開始後に配置できます。

 <header class="header-footer-group" role="banner"> <?php wp_list_categories( array('hide_empty' => FALSE) ); ?>

この関数は、カテゴリツリーのHTML出力を生成する組み込みのWordPress関数です。 デフォルトでは、投稿を含むカテゴリのみが表示されるため、 hide_emptyオプションを使用して空のカテゴリも表示し、この例では階層全体を表示します。

以前と同様に、 functions.phpでカスタムクラスを作成して、 wp-includes/class-walker-category.phpファイルに記述されているデフォルトのWalker_Categoryクラスを拡張し、変更を適用できます。 たとえば、次のコードを追加して、カテゴリ名の前にいくつかのアイコンを追加します。

 if ( !class_exists('My_Category_tree_Walker') ) { class My_Category_tree_Walker extends Walker_Category { function start_el(&$output, $item, $depth=0, $args=array(),$current_object_id = 0) { $output.= '<li><a href="'.home_url('category/'.$item->slug).'"> <img src="http://path/to/mages/'.($item->slug).'.jpg"> '.esc_attr($item->name); } } }

これが機能するためには、もちろん、適切な画像を準備し、定義されたフォルダに保存する必要があります。 これらの画像は、この例では「post-category-1」、「post-subcategory-1」、「post-category-3.jpg」などの特定の名前形式に従う必要があります。

コメントのカスタマイズ

メニューとカテゴリのリストを更新することが、ウォーカークラスをカスタマイズする最も一般的な理由ですが、コメントにも同じ手法を実装する必要がある場合があります。 たとえば、コメントセクションのGravatar画像の横にあるメタ情報を変更したい場合は、wp-includes/class-walker-comment.phpファイルにあるWalker_Commentクラスを拡張することで簡単に変更できます。

Functions.phpファイルにこのコードを追加します

if ( !class_exists('My_Comment_Walker') ) { class My_Comment_Walker extends Walker_Comment { protected function html5_comment( $comment, $depth, $args ) { $tag = ( 'div' === $args['style'] ) ? 'div' : 'li'; ?> <<?php echo $tag; ?> <?php comment_class( $this->has_children ? 'parent' : '', $comment ); ?>> <article class="comment-body"> <footer class="comment-meta"> <div class="comment-author vcard"> <?php if ( 0 != $args['avatar_size'] ) echo get_avatar( $comment, $args['avatar_size'] ); ?> <?php printf( __( '%s <span class="says">says:</span>' ), sprintf( '<span class="fn">%s</span>', get_comment_author_link( $comment ) ) ); ?> </div><!-- .comment-author --> <div class="comment-metadata"> <?php $user_id=$comment->user_id; ?> <p class="commenter-bio"><?php the_author_meta('description',$user_id); ?></p> <p class="commenter-url"><a href="<?php the_author_meta('user_url',$user_id); ?>" target="_blank"><?php the_author_meta('user_url',$user_id); ?></a></p> </div><!-- .comment-metadata --> <?php if ( '0' == $comment->comment_approved ) : ?> <p class="comment-awaiting-moderation"><?php _e( 'Your comment is awaiting moderation.' ); ?></p> <?php endif; ?> </footer><!-- .comment-meta --> <div class="comment-content"> <?php comment_text(); ?> </div><!-- .comment-content --> <?php comment_reply_link( array_merge( $args, array( 'add_below' => 'div-comment', 'depth' => $depth, 'max_depth' => $args['max_depth'], 'before' => '<div class="reply">', 'after' => '</div>' ) ) ); ?> </article><!-- .comment-body --> <?php } } }

aboutコードを元のWalker_Commentの内容と比較するとわかるように、必要な変更は、基本的にHTML5形式でコメントを出力するhtml5_commentメソッドにあります。

その後、組み込みのwp_list_comments関数を適切な引数とともに使用してコメントリストを表示し、コメントツリーのようなオブジェクトHTMLを表示する必要があります。

 wp_list_comments( array( 'page' => 143, 'walker' => new My_Comment_Walker ));

以前に行ったのと同じheader.phpの行にコードを挿入し、コメントを含む投稿のIDを使用しました。 もちろん、代わりにテンプレートのコメント関連コードを置き換えて、「ページ」オプションをスキップして、すべての記事のコメントセクションに適用することもできます。

Webサイトのフロントエンドを更新すると、上記のカスタムコードで追加した追加の情報エントリ(作成者の略歴と作成者のURL)が表示されます。

結論

上記がWordPressWalkerクラスの使用に関する洞察を与えてくれることを願っています。 すべての例で、コアテーマファイルに直接変更を適用しました。 デモンストレーションの目的には問題ありませんが、実際には子テーマにのみ編集を適用して、WordPressまたは使用されているテーマが更新されたときにこれらの更新が上書きされないようにする必要があります。