Agregar elemento personalizado de menú usando el filtro wp_nav_menu_items
He agregado un fragmento de código para añadir un enlace "Perfil" al menú de navegación de mi sitio web. Mi código:
add_filter( 'wp_nav_menu_items', 'my_nav_menu_profile_link');
function my_nav_menu_profile_link($menu) {
// Si el usuario no está conectado, devolver el menú sin cambios
if (!is_user_logged_in()){
return $menu;
} else {
$user_data = bbp_get_user_profile_url( get_current_user_id() );
$profilelink = '<li><a href="'.$user_data.'&edit" >Perfil</a></li>';
$menu = $menu . $profilelink;
return $menu;
}
}
Este código muestra correctamente el enlace del perfil en mi menú, pero ahora quiero mover este enlace "perfil" como submenú de otro menú principal.
La estructura de mi menú es la siguiente:
Inicio | Mi Cuenta | Categorías
Me gustaría agregar el enlace "perfil" debajo de "Mi Cuenta". ¿Alguna sugerencia para resolver este problema?
He creado estas dos funciones que puedes usar para agregar elementos personalizados a un elemento de menú específico presente en tu menú (página, entrada, enlace...).
En tu caso, puedes agregar estas funciones a tu archivo functions.php y llamarlas así:
$menu_name = 'Nombre de tu menú';
$name_of_menu_item_to_append_to = 'Mi Cuenta';
$id_of_menu_item_to_append_to = get_wp_object_id( $name_of_menu_item_to_append_to, 'nav_menu_item' );
$new_submenu_item = array(
'text' => 'Perfil',
'url' => 'http://algunaurl.com'
);
add_subitems_to_menu(
$menu_name,
$id_of_menu_item_to_append_to,
array( $new_submenu_item )
);
add_subitems_to_menu()
/**
* Agrega elementos personalizados a un menú de navegación
* Basado parcialmente en:
* http://teleogistic.net/2013/02/dynamically-add-items-to-a-wp_nav_menu-list/
*
* @param string $menu_name El nombre o slug del menú de navegación
* @param int $parent_object_id El ID de la entrada/página, que debe estar presente
* en el menú, y al cual queremos agregar subelementos
* @param array $subitems Los subelementos a agregar al menú, como un
* array( array( 'text' => 'foo', 'url' => '/bar') )
*/
public function add_subitems_to_menu( $menu_name, $parent_object_id, $subitems ) {
// No agregar nada en el área de administración. De lo contrario WP intentará mostrar los elementos
// en el editor de menús y no funcionará correctamente, causando comportamiento extraño
if ( is_admin() ) {
return;
}
// Usar el filtro wp_get_nav_menu_items, utilizado por Timber para obtener elementos del menú WP
add_filter( 'wp_get_nav_menu_items', function( $items, $menu )
use( $menu_name, $parent_object_id, $subitems ) {
// Si no se encuentra el menú, retornar los elementos sin agregar nada
if ( $menu->name != $menu_name && $menu->slug != $menu_name ) {
return $items;
}
// Encontrar el ID del elemento de menú correspondiente al ID del objeto de entrada/página
// Si no se encuentra la entrada/página, los subelementos no tendrán padre (estarán en 1er nivel)
$parent_menu_item_id = 0;
foreach ( $items as $item ) {
if ( $parent_object_id == $item->object_id ) {
$parent_menu_item_id = $item->ID;
break;
}
}
$menu_order = count( $items ) + 1;
foreach ( $subitems as $subitem ) {
// Crear objetos que contengan todas (y solo) las propiedades de WP_Post
// usadas por WP para crear un elemento de menú
$items[] = (object) array(
'ID' => $menu_order + 1000000000, // ID que WP no usará
'title' => $subitem['text'],
'url' => $subitem['url'],
'menu_item_parent' => $parent_menu_item_id,
'menu_order' => $menu_order,
// Estos no son necesarios, pero PHP mostrará advertencia si no están definidos
'type' => '',
'object' => '',
'object_id' => '',
'db_id' => '',
'classes' => '',
);
$menu_order++;
}
return $items;
}, 10, 2);
}
get_wp_object_id()
/**
* Devuelve el ID de WordPress de cualquier tipo de entrada o página por su título o nombre
* En caso de proporcionar un ID, lo "validará" buscando cualquier entrada con ese ID
*
* @param mixed $post_identifier El título, nombre o ID de la entrada/página
* @param string $post_type El tipo de entrada a buscar (por defecto: page)
*
* @return int El ID de la entrada/página si existe, o 0
*/
public function get_wp_object_id( $post_identifier, $post_type = 'page' ) {
$post_id = 0;
if ( get_page_by_title( $post_identifier, OBJECT, $post_type ) ) {
$post_id = get_page_by_title( $post_identifier, OBJECT, $post_type )->ID;
}
else if ( get_page_by_path( $post_identifier, OBJECT, $post_type ) ) {
$post_id = get_page_by_path( $post_identifier, OBJECT, $post_type )->ID;
}
else if ( get_post( $post_identifier ) ) {
$post_id = get_post( $post_identifier )->ID;
}
return $post_id;
}

Gracias MikO por tu ayuda
-
Mi Cuenta no es una página, he creado un enlace y lo he añadido al menú a través de la configuración del menú de wp admin
-
He verificado tu código creando una nueva página y pasando su id a la función, pero no funcionó para mí
-
He cambiado la línea $my_account_page_id = a
$my_account_item_id

Ohh Miko, ahora está funcionando, Muchas gracias por el código..
Pero en lugar de usar el id de la página, me gustaría añadir Perfil bajo un enlace, que he creado en la configuración del menú de wp admin

No hay problema, obtuve el ID del elemento del menú personalizado revisando la base de datos
Así que está solucionado, gracias de nuevo

@Hafsal, de nada. Edité mi respuesta añadiendo otra función, que puedes usar para obtener el ID de cualquier página, publicación o elemento de menú de WordPress, y actualicé la forma en que deberías llamar a estas funciones. De otra manera, puedes revisar directamente el ID en la base de datos como lo has hecho...
