it-swarm.com.de

Anzahl der Elemente in einem Menü

Ich kann nicht feststellen, ob WordPress die Anzahl der Elemente in einem Menü speichert. Grundsätzlich muss ich herausfinden, wie viele Elemente sich in einem Menü befinden, um den Prozentsatz zu ermitteln, den jedes Element in der Kopfzeile aufnehmen soll. Gibt es eine Funktion? Oder geht das am besten mit WP_Query?

2
Chess Byte

Ich war neugierig und habe mich entschlossen, es auszuprobieren, egal ob es für ein CSS-Problem relevant ist ;-)

Ich habe zuerst in die Datenbanktabellen geschaut, um mehr über die Menüstruktur zu erfahren:

Menü - Bausteine

Jedes Navigationsmenü ist in der Taxonomie nav_menu als Begriff registriert.

Wenn wir diesem Menü dann Elemente hinzufügen, erstellen wir neue Post-Objekte vom Typ nav_menu_item.

Nun der schwierige Teil, wo ist die Baumstruktur für dieses Menü gespeichert?

Es ist nicht wie erwartet das, was im post_parent-Feld der nav_menu_item-Posts gespeichert ist.

Wir finden es tatsächlich in der Post-Meta-Tabelle, in der es unter dem _menu_item_menu_item_parent-Metaschlüssel für jeden nav_menu_item-Post gespeichert ist.

Nun gibt es verschiedene Möglichkeiten, die Zählung durchzuführen. Hier einige Beispiele:

Beispiel - get_term_by()/wp_get_nav_menu_object()

Zunächst das Einfache: Wenn wir die Anzahl der Elemente in einem bestimmten Menü benötigen, können wir sie tatsächlich aus einer Begriffsabfrage abrufen, da sie in der Spalte count der Tabelle wp_term_taxonomy gespeichert ist.

Zuerst bekommen wir den Menübegriff mit:

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

Dafür gibt es einen Wrapper, nämlich:

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

Um die Gesamtzahl der Elemente im Menü zu erhalten, können wir dann Folgendes verwenden:

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

Beispiel - WP_Query()/get_posts()

Wenn wir nur Menüpunkte ohne Eltern zählen wollen, können wir alle Beitragsobjekte in unserem Menü sammeln mit:

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

dabei steht $pids für ein Array von Post-IDs.

Dann können wir die folgende Meta-Abfrage machen:

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

Es gibt auch einen Weg mit:

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

oder nur:

$count = $q->found_posts;

mit dem allgemeinen Trick, posts_per_page als 1, werden abgerufene Daten reduziert.

Beispiel - wp_get_nav_menu_items()

Im Kern gibt es nützliche Wrapper wie wp_get_nav_menu_items( $menu, $args ), wobei $argsget_posts()-Argumente sind.

Hier ist eine Möglichkeit:

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

Wir können auch verwenden:

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

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

Beispiel - Filter/Haken

Es gibt viele Filter/Aktionen, mit denen wir die Zählung durchführen könnten, z. der wp_get_nav_menu_items filter. Sogar Haken im Navigationsmenü.

Wir könnten uns sogar in den wp_update_nav_menu einklinken, der ausgelöst wird, wenn das Menü aktualisiert wird. Dann könnten wir die Gegenstände ohne Eltern zählen und sie z. als Begriff Metadaten.

Dann gibt es mit Javascript auch verschiedene Möglichkeiten.

Hoffentlich gibt Ihnen dies einige Anregungen, um dies weiter voranzutreiben.

5
birgire

Danke für die Hilfe birgire. Das gab mir viel zu denken. Schließlich habe ich eine Lösung mit einem Filter gefunden, mit dem ich die Anzahl der Eltern zählen kann, die das Menü hat. Das einzige Problem bei diesem Ansatz ist, dass er jedes Mal ausgeführt wird, wenn ein Menü angezeigt wird.

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

Ändern Sie das "header_menu" in die Position Ihrer Navigation, die Sie überprüfen möchten. Sie können dies dann in einer Option speichern und bei Bedarf aufrufen.

1
Chess Byte