web-dev-qa-db-ja.com

メニュー内の項目数

WordPressがメニュー内のアイテムの数を保存しているかどうか私にはわかりません。基本的に、各項目がヘッダーバーに占める割合を算出するには、メニューに含まれる項目の数を調べる必要があります。機能はありますか?それとも、これを達成するための最善の方法はWP_Queryで何かをすることですか?

2
Chess Byte

私は興味があり、CSSの問題に関連しているかどうかにかかわらず、チェックアウトすることにしました;-)

私は最初にデータベーステーブルを覗いて、メニュー構造についてもっと知りました:

メニュー - ビルディングブロック

各ナビゲーションメニューは、nav_menu分類法の用語として登録されています。

そのメニューにアイテムを追加すると、nav_menu_item型の新しい投稿オブジェクトが作成されます。

ここで注意が必要なのは、そのメニューのツリー構造はどこに格納されているのでしょうか。

予想通り、post_parent投稿のnav_menu_itemフィールドに格納されているものではありません。

実際には、それぞれの_menu_item_menu_item_parent投稿について、nav_menu_itemメタキーの下に格納されているpostメタテーブルにあります。

今すぐカウントを取得するさまざまな方法があります。いくつか例を挙げます。

例 - get_term_by()/wp_get_nav_menu_object()

まず簡単な方法:特定のメニューの項目数を取得する必要がある場合、実際はtermクエリから取得できます。これはwp_term_taxonomyテーブルのcount列に格納されているためです。

まず、メニューの用語を以下のようにして得ます。

$menuterm = get_term_by( 'slug', 'some-menu-slug', 'nav_menu' );

これに対するラッパーがあります。

$menuterm = wp_get_nav_menu_object( 'some-menu-slug' );

メニュー内のアイテムの総数を取得するには、次のようにします。

$total_count = ( $menuterm instanceof \WP_Term ) ? $menuterm->count : 0;

例 - WP_Query()/get_posts()

親なしでメニュー項目だけをカウントしたい場合は、次のようにしてメニュー内のすべての投稿オブジェクトを収集できます。

if( $menuterm instanceof \WP_Term )
   $pids = get_objects_in_term( $menuterm->term_id, 'nav_menu' );

$pidsは投稿IDの配列です。

それから私達は次のメタクエリを作ることができます:

$args = [
    'post__in'            => $pids,
    'post_type'           => 'nav_menu_item',
    'fields'              => 'ids',
    'ignore_sticky_posts' => true,
    'nopaging'            => true,
    'meta_query'          => [
        [
            'key'       => '_menu_item_menu_item_parent',
            'value'     => 0,
            'compare'   => '=',
        ]
    ]
]; 

$count = count( get_posts( $args ) );

との方法もあります:

$q = new WP_Query();
$count = count( $q->query( $args ) );

あるいは単に:

$count = $q->found_posts;

フェッチされたデータを減らすための一般的なトリック、posts_per_pageを1にします。

例 - wp_get_nav_menu_items()

$argswp_get_nav_menu_items( $menu, $args )引数であるget_posts()のような、便利なラッパーがコアに存在します。

これが一つの方法です:

$count = count( 
    wp_list_filter( 
        wp_get_nav_menu_items( 'some-menu-slug' ), 
       [ 'menu_item_parent' => 0 ] 
    ) 
);

私達はまた使用してもいいです:

$args = [
    'meta_query'    => [
        [
            'key'       => '_menu_item_menu_item_parent',
            'value'     => 0,
            'compare'   => '=',
        ]
    ]
];

$count = count( wp_get_nav_menu_items( 'some-menu-slug', $args ) );

例 - フィルター/フック

カウントを行うためにフックすることができる多くのフィルタ/アクションがあります。 wp_get_nav_menu_itemsフィルタナビゲーションメニューウォーカー内でさえフックします。

メニューが更新されたときに起動するwp_update_nav_menuにフックすることもできます。それから私達は両親なしでアイテムを数えてそれを保存することができます。用語メタデータとして。

それからjavascriptにはいろいろな方法があります。

うまくいけば、これはあなたにこれをさらに進めるためのいくつかのアイデアを与えるでしょう。

5
birgire

助けbirgireをありがとう。それは私に考えることをたくさん与えました。結局、私はメニューが持っている親の数を数えることができるフィルタを使って解決策を思いついた。この方法の唯一の問題は、メニューが表示されるたびに実行されることです。

function my_nav_menu_objects($sorted_menu_items, $args) 
{
  if($args->menu == 'header_menu')
  {
    $counter = 0;

    foreach($sorted_menu_items as $sorted_menu_item)
    {
      if($sorted_menu_item->menu_item_parent == 0) 
      {
        $counter++;
      }
    }

    echo 'Menu Count: ' . $counter;
  }

  return $sorted_menu_items;
}
add_filter('wp_nav_menu_objects', 'my_nav_menu_objects', 10, 2);

"header_menu"をナビゲーションのスラッグをチェックしたいものに変更してください。これをオプションに格納して、必要に応じて呼び出すことができます。

1
Chess Byte