Cómo codificar elementos personalizados del menú de forma manual

23 abr 2011, 19:24:11
Vistas: 44.4K
Votos: 23

¿Hay alguna manera de codificar manualmente los elementos del menú personalizado cuando se instala el tema por primera vez? Estoy creando un tema que creará automáticamente algunas páginas comunes cuando se instale. Necesito saber si también puedo agregarlas al menú personalizado de WordPress para que el cliente no necesite agregarlas manualmente.

En otras palabras: ¿cómo insertar/crear elementos de menú personalizados programáticamente?

Háganme saber si algo no está claro. ¡Cualquier guía a la página del codex apropiada es bienvenida. ¡Gracias!


actualización: probé el código de aquí Apuntando a un menú específico con wp_nav_menu_items

Registro del menú:

function register_my_menus() {
  register_nav_menus(
    array('main-menu' => __( 'Menú Principal' ) )
  );
}

add_action( 'init', 'register_my_menus' );

Uso en la plantilla:

<?php wp_nav_menu( array( 'theme_location' => 'main-menu' ) ); ?>

Código para agregar nuevos elementos:

function new_nav_menu_items($items) {
    if( $args->theme_location == 'main-menu' ){
    $homelink = '<li class="home"><a href="' . home_url( '/' ) . '">' . __('Inicio') . '</a></li>';
    $items = $homelink . $items;
    return $items;
    }
}
add_filter( 'wp_nav_menu_items', 'new_nav_menu_items', 10, 2 );

Cuando agrego el código para añadir nuevos elementos en el menú de navegación en el archivo functions.php no sucede nada en la página del menú en el panel de administración, ¡pero los elementos actuales del menú desaparecen en el sitio!

0
Todas las respuestas a la pregunta 4
14
25

El problema con tu código es que en realidad no está agregando los enlaces al menú, solo a la salida del menú, por eso se usa un filtro (add_filter), así que solo estás filtrando la salida del menú. De hecho, incluso si no tienes un menú, tu enlace se mostrará con el código que estás usando. Pero para crear un enlace y agregarlo a un menú, puedes usar este código:

$run_once = get_option('menu_check');
if (!$run_once){
    //asigna un nombre a tu menú
    $name = 'menú predeterminado del tema';
    //crea el menú
    $menu_id = wp_create_nav_menu($name);
    //luego obtén el objeto del menú por su nombre
    $menu = get_term_by( 'name', $name, 'nav_menu' );

    //luego agrega el enlace/ítem del menú y haz esto por cada ítem que quieras agregar
    wp_update_nav_menu_item($menu->term_id, 0, array(
        'menu-item-title' =>  __('Inicio'),
        'menu-item-classes' => 'home',
        'menu-item-url' => home_url( '/' ), 
        'menu-item-status' => 'publish'));

    //luego asignas la ubicación deseada en el tema
    $locations = get_theme_mod('nav_menu_locations');
    $locations['main-menu'] = $menu->term_id;
    set_theme_mod( 'nav_menu_locations', $locations );

    // luego actualizas la opción menu_check para asegurarte de que este código solo se ejecute una vez
    update_option('menu_check', true);
}

He comentado todo para hacerlo más simple.

Para crear una página secundaria/subpágina/menú de segundo nivel (como quieras llamarlo), solo necesitas establecer el menu-item-parent-id en el nuevo ítem, por ejemplo:

//crea el ítem de menú de nivel superior (inicio)
$top_menu = wp_update_nav_menu_item($menu->term_id, 0, array( 
    'menu-item-title' =>  __('Inicio'),
    'menu-item-classes' => 'home',
    'menu-item-url' => home_url( '/' ), 
    'menu-item-status' => 'publish'
    'menu-item-parent-id' => 0,
    ));
//Sub ítem de menú (primer hijo)
$first_child = wp_update_nav_menu_item($menu->term_id, 0, array( 
    'menu-item-title' =>  __('Primer_Hijo'),
    'menu-item-classes' => 'home',
    'menu-item-url' => home_url( '/' ), 
    'menu-item-status' => 'publish'
    'menu-item-parent-id' => $top_menu,
    ));
//Sub Sub ítem de menú (segundo hijo)
$Second_child = wp_update_nav_menu_item($menu->term_id, 0, array( 
    'menu-item-title' =>  __('Segundo_Hijo'),
    'menu-item-classes' => 'home',
    'menu-item-url' => home_url( '/' ), 
    'menu-item-status' => 'publish'
    'menu-item-parent-id' => $first_child,
    ));

También puedes establecer la posición mediante código con menu-item-position y creo que se hace así:

  • Primer ítem - 'menu-item-position' => 1
    • Primer hijo del primer ítem - 'menu-item-position' => 1
    • Segundo hijo del primer ítem - 'menu-item-position' => 1
      • Primer hijo del segundo hijo del primer ítem - 'menu-item-position' => 1
  • Segundo ítem - 'menu-item-position' => 2
  • 3er ítem - 'menu-item-position' => 3
  • 4to ítem - 'menu-item-position' => 4
24 abr 2011 06:03:11
Comentarios

Esas son las funciones que estaba buscando :) el codex no las incluía :( Una pregunta más, ¿cómo puedo agregar un elemento hijo al elemento Home? Te avisaré en cuanto llegue a mi PC. ¡Gracias!

Sisir Sisir
24 abr 2011 20:42:31

@Sisir: actualicé con un ejemplo de cómo crear páginas hijas

Bainternet Bainternet
25 abr 2011 03:12:57

@Bainternet: obtuve este error al ejecutar el código por primera vez Fatal error: Cannot use object of type stdClass as array in C:\wamp\www\citystir\wp-admin\menu.php on line 25. Pero el menú se crea y cuando se actualiza la página todo funciona, aunque no aparece nada en la sección Apariencia -> Ubicación del menú en el tema. ¡Estamos muy cerca! ¡Gracias!

Sisir Sisir
28 abr 2011 22:36:24

@Bainternet: Mi suposición es que el código está generando un error cuando intenta ejecutar $locations = get_theme_mod('nav_menu_locations'); Así que, el código antes de eso (toda la inserción del menú se completa) se ejecuta pero el código después (establecer la ubicación deseada en el tema) no se ejecuta.

Sisir Sisir
28 abr 2011 22:48:38

@Sisir: el código funciona perfectamente, ¿cuál es el nombre de la ubicación de tu tema y muéstrame el código exacto que estás usando? Veré si puedo ayudarte.

Bainternet Bainternet
29 abr 2011 03:26:01

@Bainternet: Aquí http://pastebin.com/Px16q43a. Usé pastebin.

Sisir Sisir
29 abr 2011 19:35:00

@Sisir: ¿cuál es el nombre de la ubicación de tu menú?

Bainternet Bainternet
29 abr 2011 21:46:52

usé este código en el menú de navegación wp_nav_menu( array( 'theme_location' => 'main-menu' ) ); así que supongo que el nombre de la ubicación del tema es main-menu, ¿correcto?

Sisir Sisir
30 abr 2011 10:54:09

sí, pero aún necesitas registrar esta ubicación del tema usando register_nav_menu( $location, $description ); antes de intentar asignar un menú a esa ubicación.

Bainternet Bainternet
30 abr 2011 15:04:16

@Bainternet: ¡Gracias! El nombre de la ubicación del tema ahora se muestra. Pero el error seguía ahí hasta que lo puse en una función y luego agregué la función en mi página de opciones del tema. Ahora solo se ejecutará cuando se haga clic en el botón. Parece que así el error desapareció. Todo funciona bien ahora. Gracias por toda tu ayuda. Espero que siempre llegues a mis preguntas ;)

Sisir Sisir
1 may 2011 14:19:45

Me alegra que lo hayas logrado.

Bainternet Bainternet
1 may 2011 17:00:05

@Bainternet: Hola, he tenido que molestarte de nuevo :) Con la función wp_update_nav_menu_item() los elementos del menú se agregan como enlaces personalizados. ¿Hay alguna manera de agregar elementos del menú de tipo publicación o página? Esto es porque ahora cuando actualizo mi enlace permanente, los enlaces personalizados no se actualizan. Pero si fuera un elemento del menú de tipo página, se actualizaría automáticamente. Creo que me expliqué bien. ¡Gracias!

Sisir Sisir
23 may 2011 23:50:13

@Bainternet: Hola, el atributo menu-item-position debe ser incremental desde el elemento superior del menú hasta el inferior, sin importar si hay subelementos o no. Encontré esto aquí: http://www.acousticwebdesign.net/wordpress/how-to-create-wordpress-3-navigation-menus-in-your-theme-or-plugin-code/.

Clawsy Clawsy
12 may 2016 09:46:10

¡Incluso 9 años después, información aún útil!

Beee Beee
6 dic 2020 02:54:57
Mostrar los 9 comentarios restantes
1
12

Tu código original está muy cerca de ser correcto y realmente creo que esta solución larga de @Bainternet (sin ofender) es excesiva, así que mira esto en su lugar:

function new_nav_menu_items($items, $args) {
    if( $args->theme_location == 'primary' ){
        $homelink = '<li class="home"><a href="' . home_url( '/' ) . '">' . __('Home') . '</a></li>';
        $items = $homelink . $items;
    }
    return $items;
}
add_filter( 'wp_nav_menu_items', 'new_nav_menu_items', 10, 2 );

Tu único problema era que no estabas devolviendo $items después de que la función verificara el menú correcto, y te faltaba el segundo argumento de callback necesario para hacer la verificación ($args).

1 ago 2012 13:43:05
Comentarios

¿Cómo configurarías la ubicación del elemento del menú usando este método?

User User
4 nov 2014 03:05:11
0

Hay un error en WordPress 3.4.2:

https://github.com/WordPress/WordPress/commit/ae96b842f9f55ecfb22da705a4902b9d25580259#wp-includes/nav-menu.php

Necesitas crear la relación del término manualmente:

$menu = wp_get_nav_menu_object('menú superior');  // Obtiene el objeto del menú llamado 'menú superior'
$id = wp_update_nav_menu_item($menu->term_id, 0, $data);  // Actualiza o crea un ítem de menú

if ($menu->term_id && (!is_object_in_term($id, 'nav_menu', (int)$menu->term_id))) {
    wp_set_post_terms($id, array((int)$this->id), 'nav_menu');  // Establece la relación del término si no existe
}

Consulta https://gist.github.com/4148529 para ver un ejemplo de la clase Menu para la creación sencilla de menús.

26 nov 2012 16:29:38
0

Para información, el usuario actual debe tener los derechos para agregar términos, mis menu_items fueron creados pero no añadidos en la tabla wp_terms_relationship antes de que agregara una llamada a wp_set_current_user(1);

2 ago 2013 16:43:18