web-dev-qa-db-ja.com

1レベルの子ページだけを表示する、wp_list_pages

私は数レベルのかなり大きなページ構造を持つサイトに取り組んでいます - いくつかのセクションではたくさんのページがあります。

基本的な設定はこのようなものです...

親
親
親
  - 子
  - 子
  - 孫
  - 孫
  - 孫
 - 孫
  - 孫
  - 孫
  - 孫
  - 孫
  - 孫
  - 孫
  - 孫
 - 孫
  - 偉大な孫
  - 子
親
  - 子
親
親
  - 子供
  - 子供
  - 孫
 --- GreatGrandchild 
  - 孫

あなたは写真を手に入れます - もっとたくさんのページを想像してみてください。

サブメニューの私の通常の解決策は、私がはるかに小さなサイトに取り組んでいるので、正常に動作します(Codexから直接取られます)。このサイトは非常に長いメニューになっていて、それは役に立つには大きすぎます。

私がやりたいことは、現在表示されているページの下に 直接 のレベルを表示することです。基本的には「このセクションに...」メニューがあります。

どのようなwp_list_pagesスニペットの組み合わせを使用しても、取得できるのはまったく、またはまったくできません。

また、子供がいないセクションもあるので、子供がいないときはトップレベルのリンクを表示するだけで済みます。

うまくいけば、それは理にかなっている - 私はこれ以上一日中私の髪を引き裂いてきた!どうぞよろしくお願いいたします。

編集

そう、私はここでそれを宣伝します。 noobであることで申し訳ありません!

ここまで来てくれた@ chip-bennetに感謝します。

私は今、私が必要とするほとんどすべてを実行するこのコードを手に入れました。

$output = wp_list_pages('echo=0&depth=1&title_li=Sections' );

        if (is_page( )) {

          $page = $post->ID;

          if ($post->post_parent) {
            $page = $post->post_parent;
          }

          $children=wp_list_pages( 'echo=0&child_of=' . $page . '&title_li=' );


          if ($children) {
            $output = wp_list_pages( array(
                // Only pages that are children of the current page
                'child_of' => $post->ID,
                // Only show one level of hierarchy
                'depth' => 1,
                'title_li' => 'In this Section'
            ) );
          }


        } 

        echo $output;

何も出力されないとき、これは私がツリーの一番下にぶつかるまで私が望むように正確に働きます。

Chipは私にもっと多くの子供を探すのではなく、ページの仲間を表示するためのコードを再度提供してくれました - しかし、私の適切なPHPスキルの欠如は、私がこのコードにそれを追加するのに問題があることを意味します。

5
a_kc

このshouldは、 wp_list_pages() に利用可能な引数配列パラメータ、具体的にはdepthchild_of以外は何も使用せずに動作します。

現在のページの子孫ページについて、1レベルの階層を表示するには、次の手順を実行します。

<?php
// Globalize the $post variable;
// probably already available in this context, but just in case...
global $post;
wp_list_pages( array(
    // Only pages that are children of the current page
    'child_of' => $post->ID,
    // Only show one level of hierarchy
    'depth' => 1
) );
?>

カスタムウォーカークラスに頼る必要はないはずです。

_編集_

トップレベルのリンクも表示するには、単純にいくつかのパラメータを変更します。

<?php
// Globalize the $post variable;
// probably already available in this context, but just in case...
global $post;
wp_list_pages( array(
    // Only pages that are children of the current page's parent
    'child_of' => $post->post_parent,
    // Only show two level of hierarchy
    'depth' => 2
) );
?>

現在のページの親ページのページを含む'child_of' => $post->IDから'child_of' => $post->post_parentへの変更、および現在のページの兄弟とその子を含む'depth' => 1から'depth' => 2への変更に注意してください。

編集2

さて、これが私があなたがちょうど追加したコードを処理する方法です。まず、配列文字列ではなく適切な配列を使用します。それから、context/child-pages beforeを問い合わせてwp_list_pages()引数配列を構築し、それからwp_list_pages()を一度だけ呼び出します。

// Use parent page if exists, else use current page    
$child_of_value = ( $post->post_parent ? $post->post_parent : $post->ID );
// Depth of 2 if parent page, else depth of 1
$depth_value = ( $post->post_parent ? 2 : 1 );
// Build argument array
$wp_list_pages_args = array( 
    'child_of' => $child_of_value,
    'depth' => $depth_value,
    'title_li' => 'Sections'
);
// Now, output the result
wp_list_pages( $wp_list_pages_args );

実際に別々のリストを出力する必要がある場合は、もっと複雑なコードが必要です。

8
Chip Bennett

それで、depth引数を使用して表示したいレベル数を制御できます。現在のページの直接の子から始まるメニューを表示するSubMenuウォーカーを作成しました。コード:

class My_Walker_Submenu extends Walker_Nav_Menu {


  function display_element($element, &$children_elements, $max_depth, $depth = 0, $args, &$output) {

    if (! $element)
      return;

    $itemId = null;

    if ( $depth == 0) {
        if (!isset($args[0]->child_of)){
         return;
        }
      foreach ( $children_elements as $id => $children ) {
        $data = get_post_meta ( $id, '_menu_item_object_id', true );
        if ($data == $args [0]->child_of) {
          $itemId = $id;
          break;
        }
      }
      if ($itemId == null) {
        return;
      }
      unset($args [0]->child_of);

      foreach ( $children_elements [$itemId] as $child ) {
        parent::display_element ( $child, $children_elements, $max_depth, $depth + 1, $args, $output );
      }
      return;

    }
    return parent::display_element ( $element, $children_elements, $max_depth, $depth, $args, $output );
  }

使い方(私は実際にサイドバーで使っています):

echo wp_nav_menu( array(
              'container' => '',
              'theme_location' => 'header-menu',
              'walker' => new My_Walker_Submenu(),
              'child_of' => $page->ID, 
              'depth'   => 2
) );
2

これを実現するためにwp_list_pages()を使用する関数を作成しました。パラメータを微調整すれば、すべて設定完了です。

要旨

0
Simon

これは私がよく見かける問題です。私はWordPressが適切なメニューマネージャを持っているので(Appearance - > Menus)、WP_List_Pagesの解決策は少し古い学校だと思います。

私は上記のようないくつかのプラグイン/ウィジェットやウォーカーを含む多数の解決策を試してみました。私は利用可能な解決策にとても満足していません。私はこれらの二次メニューを私が好む方法に慣れ親しんだ方法で扱う私自身のプラグインを作成しました。メニューを表示するときは、現在のページより上の特定の数の「レベル」を無視するようにメニューに通知するようにstart_depthを設定できます。

それであなたの必要性のためにあなたは1にstart_depthをセットするでしょう、そしてそれはあなたのメニューを表示するとき自動的にトップレベルのナビゲーション項目を無視するでしょう。

私はプラグインWP Nav Plusと呼んでいます。なぜならそれは子メニューを表示するためのstart_depth引数を追加しただけで現在のwp_nav_menuの能力とオプションの上に構築されているからです。

興味がある人のためにそれは私のウェブサイトで利用可能です: https://mattkeys.me/products/wp-nav-plus/

0
Matt Keys