Добавить пользовательский пункт меню с помощью фильтра wp_nav_menu_items
Я добавил сниппет для добавления ссылки "Профиль" в навигационное меню моего сайта. Мой код:
add_filter( 'wp_nav_menu_items', 'my_nav_menu_profile_link');
function my_nav_menu_profile_link($menu) {
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" >Профиль</a></li>';
$menu = $menu . $profilelink;
return $menu;
}
}
Этот код правильно отображает ссылку на профиль в моем меню, но теперь я хочу переместить эту ссылку "профиль" как подменю другого главного меню.
Структура моего меню выглядит следующим образом:
Главная | Мой аккаунт | Категории
Я хотел бы добавить ссылку "профиль" под пункт "Мой аккаунт". Есть ли предложения, как решить эту проблему?
Я создал эти две функции, которые вы можете использовать для добавления пользовательских элементов к определенному пункту меню (странице, записи, ссылке...).
В вашем случае, вы можете добавить эти функции в ваш файл functions.php и вызвать их следующим образом:
$menu_name = 'Название вашего меню';
$name_of_menu_item_to_append_to = 'Мой аккаунт';
$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' => 'Профиль',
'url' => 'http://someurl.com'
);
add_subitems_to_menu(
$menu_name,
$id_of_menu_item_to_append_to,
array( $new_submenu_item )
);
add_subitems_to_menu()
/**
* Добавляет пользовательские элементы в навигационное меню
* Частично основано на:
* http://teleogistic.net/2013/02/dynamically-add-items-to-a-wp_nav_menu-list/
*
* @param string $menu_name Название или слаг навигационного меню
* @param int $parent_object_id ID записи/страницы, которая должна присутствовать
* в меню, и к которой мы хотим добавить подпункты
* @param array $subitems Подпункты для добавления в меню, в виде
* массива array( array( 'text' => 'foo', 'url' => '/bar') )
*/
public function add_subitems_to_menu( $menu_name, $parent_object_id, $subitems ) {
// Не добавляем ничего в админке. Иначе WordPress попытается отобразить элементы в
// редакторе меню, что приведет к странному поведению
if ( is_admin() ) {
return;
}
// Используем фильтр wp_get_nav_menu_items, который используется Timber для получения элементов меню WP
add_filter( 'wp_get_nav_menu_items', function( $items, $menu )
use( $menu_name, $parent_object_id, $subitems ) {
// Если меню не найдено, просто возвращаем элементы без добавления
if ( $menu->name != $menu_name && $menu->slug != $menu_name ) {
return $items;
}
// Находим ID пункта меню, соответствующего заданному ID объекта записи/страницы
// Если запись/страница не найдена, подпункты не будут иметь родителя (будут на 1 уровне)
$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 ) {
// Создаем объекты, содержащие все (и только) те свойства из WP_Post,
// которые использует WP для создания пункта меню
$items[] = (object) array(
'ID' => $menu_order + 1000000000, // ID, который WP не использует
'title' => $subitem['text'],
'url' => $subitem['url'],
'menu_item_parent' => $parent_menu_item_id,
'menu_order' => $menu_order,
// Эти свойства не обязательны, но PHP выдаст предупреждение, если они не определены
'type' => '',
'object' => '',
'object_id' => '',
'db_id' => '',
'classes' => '',
);
$menu_order++;
}
return $items;
}, 10, 2);
}
get_wp_object_id()
/**
* Возвращает ID любого типа записи или страницы WordPress по ее заголовку или названию
* В случае, если вы передаете ID, функция проверит его наличие среди записей с таким ID
*
* @param mixed $post_identifier Заголовок, название или ID записи/страницы
* @param string $post_type Тип записи для поиска (по умолчанию: page)
*
* @return int ID записи/страницы, если найдена, или 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;
}

Спасибо, МикО, за вашу помощь
-
Мой аккаунт - это не страница, я создал ссылку и добавил её в меню через настройки меню в админке WordPress
-
Я проверил ваш код, создав новую страницу и передав её ID в функцию, но это не сработало для меня
-
Я изменил строку $my_account_page_id = на
$my_account_item_id

О, МикО, теперь это работает, большое спасибо за код..
Но вместо использования ID страницы я хотел бы добавить Профиль под ссылкой, которую я создал в настройках меню админки WordPress

Без проблем, я получил ID пользовательского пункта меню, проверив в базе данных
Так что проблема решена, еще раз спасибо

@Hafsal, пожалуйста. Я отредактировал свой ответ, добавив другую функцию, которую вы можете использовать для получения ID любой страницы, записи или пункта меню в WordPress, и обновил способ вызова этих функций. В противном случае, вы можете проверить ID напрямую в БД, как вы и сделали...
