it-swarm-eu.dev

wp_get_nav_menu_items () nepracuje se slugem

Podle docs , wp_get_nav_menu_items() parametr 1 přijme

(string) (Required) Menu name, ID, or slug.

Zde je návod, jak registruji menu

register_nav_menus(
    array(
        'primary' => 'Navigation primaire',
        'secondary' => 'Navigation secondaire',
    )
);

Zde je, jak jsem se pokusil načíst jeden

var_dump( wp_get_nav_menu_items('primary') );             // bool(false)
var_dump( wp_get_nav_menu_items('navigation-primaire') ); // bool(false)
var_dump( wp_get_nav_menu_items('Navigation primaire') ); // bool(false)

var_dump( wp_get_nav_menu_items(51) );                      // array([...]) (correct)

Funkce tedy vrátí nabídku pouze při použití ID. Raději bych použil slug, protože moje stránky jsou vícejazyčné a nechci používat různé ID v závislosti na jazyce.

Dělám něco špatně nebo je to základní chyba? Zkoušel jsem to na téma TwentySixteen s vícejazyčným pluginem zakázaným (Polylang).

6
Brian

Protože nikdo opravdu nevysvětlil, proč tato funkce nefunguje tak, jak jste si mysleli, že to udělal, vezmu si bodnutí na detail, jak jsem právě padl na stejnou past, jako jste to udělali.

To je místo, kde dokumenty nejsou opravdu jasné, co se o slug odkazuje. Většina lidí by předpokládala, že se zaregistroval v registrovaném menu, ale to není správné. Je to vlastně slug termínu pro taxonomii nav_menu.

Umožňuje ponořit se do zdrojového kódu a zjistit, jak jádro Wordpressu interpretuje slimák z menu.

function wp_get_nav_menu_items( $menu, $args = array() ) {
    $menu = wp_get_nav_menu_object( $menu );
....

První řádek ukazuje, že používá funkci s názvem wp_get_nav_menu_object () k načtení nabídky. Předává $menu jako první parametr této funkci. Protože to je to, co používáme pro náš slug, budeme se muset ponořit do zdroje wp_get_nav_menu_object().

function wp_get_nav_menu_object( $menu ) {
    $menu_obj = false;

    if ( is_object( $menu ) ) {
            $menu_obj = $menu;
    }

    if ( $menu && ! $menu_obj ) {
            $menu_obj = get_term( $menu, 'nav_menu' );

            if ( ! $menu_obj ) {
                    $menu_obj = get_term_by( 'slug', $menu, 'nav_menu' );
            }

            if ( ! $menu_obj ) {
                    $menu_obj = get_term_by( 'name', $menu, 'nav_menu' );
            }
    }
....

vidíme, že tato funkce používá funkci get_term_by k načtení $menu_obj. To je místo, kde jsme si naše menu.

Když vytvoříte menu v administrační oblasti Wordpressu, vytvoří nový termín. Pojmy, mají slimáky založené mimo své jméno. Takže pokud máte název menu "Moje Awesome Menu" Wordpress bude generovat slug s názvem "my-awesome-menu". Možná jste menu zaregistrovali jako "primární", ale to není slug tyto funkce odkazují. Je to vlastně menu termín slug.

Abychom byli jasní, řekněme, že jste takovou nabídku zaregistrovali takto:

register_nav_menu('primary', 'my primary nav');

primary není slug. my-primary-nav také není slimák.

Vzhledem k tomu, že jsme vytvořili nabídku s názvem „Moje úžasná nabídka“ (jako příklad) a slug je „moje úžasná nabídka“, můžete ji získat takto:

$awesome_menu = wp_get_nav_menu_items( 'my-awesome-menu' );

Můžete se sami přesvědčit, co je to slug, stačí zkontrolovat tabulku v tabulce wp_terms (nebo jakákoliv vaše předpona) a vyhledat tam název vaší nabídky.

Vzhledem k tomu, že používáte vícejazyčné stránky nebo dokonce více stránek, nebude tato metoda nejlepším způsobem, jak na to jít. Protože jméno a slug by mohly být jiné.

Nejvhodnější metodou je získat všechna umístění menu pomocí get_nav_menu_locations(), které vrátí asociativní pole, kde klíč je slim z registrované nabídky a hodnota je id termínu nabídky vybraného pro jeho umístění.

S termínem id, můžeme získat, že termíny info a pak vrátit správné slug funkce vyžaduje.

Níže je funkce, která využívá funkci wp_get_nav_items(), ale prošli byste v registrovaném menu. Ve vašem případě by to bylo „primární“.

Řešení kódů

// kind of a long function name but whatevs
function get_menu_items_by_registered_slug($menu_slug) {

    $menu_items = array();

    if ( ( $locations = get_nav_menu_locations() ) && isset( $locations[ $menu_slug ] ) ) {
        $menu = get_term( $locations[ $menu_slug ] );

        $menu_items = wp_get_nav_menu_items($menu->term_id);


    }

    return $menu_items;

}
12
JoeMoe1984

Malá změna přijaté odpovědi

Po odstranění nabídky z umístění nabídky se $locations[ $menu_slug ] vrátí 0, takže je dobré tuto kontrolu přidat:

function get_menu_items_by_registered_slug($menu_slug) {
  $menu_items = array();

  if ( ($locations = get_nav_menu_locations()) && isset($locations[$menu_slug]) && $locations[$menu_slug] != 0 ) {
    $menu = get_term( $locations[ $menu_slug ] );
    $menu_items = wp_get_nav_menu_items($menu->term_id);
  }

  return $menu_items;
}
1
Narek

Zkuste to:

    $menu_name = 'primary'; 

    if ( ( $locations = get_nav_menu_locations() ) && isset( $locations[ $menu_name ] ) ) {
        $menu = wp_get_nav_menu_object( $locations[ $menu_name ] );

        $menu_items = wp_get_nav_menu_items($menu->term_id);
        // Your output code
    }
0
Ignat B.
custom_menu('primary');

function custom_menu( $theme_location ) {
if ( ($theme_location) && ($locations = get_nav_menu_locations()) && isset($locations[$theme_location]) ) {
    $menu = get_term( $locations[$theme_location], 'nav_menu' );
    $menu_items = wp_get_nav_menu_items($menu->term_id);
    //your menu code.
}
0