Доброго времени суток.
Недавно в одном небольшом проекте на WordPress мне понадобилось динамически изменять пункты меню.
Немного погуглив я не получил того варианта, на который рассчитывал — все вариант были либо дико неудобные, либо терялся нужный функционал, а главное — возможность всё так-же редактировать меню из админ-панели.
Стоит отметить, что с WP я работаю ~2 месяца, некоторых аспектов, я конечно же, ещё не знаю, но гуглениями я пришёл к функции wp_update_nav_menu_item(), которой, почему-то, не оказалось в документации, но она оказалась как-раз тем, что нужно.
Функция расположена в /wp-includes/nav-menu.php и принимает 3 параметра - $menu_id, $menu_item_db_id и $menu_item_data.
Давайте рассмотрим каждый параметр по-отдельности:
$menu_id — integer — идентификатор меню. Когда вы создаёте новое меню (точнее сказать регистрируете) в своём functions.php, то каждому меню присваивается идентификатор.
$menu_item_db_id — integer — когда вы создаёте элементы меню, то каждому присваивается идентификатор и идентификатор в базе данных (обычно они совпадают). Если этот параметр установить 0, то функция создат новый элемент, а не обновит существющий.
$menu_item_data — array — массив данных для элемента, который вы собираетесь обновить или создать.
Вомзожные параметры:
- menu-item-db-id
- menu-item-object-id
- menu-item-object
- menu-item-parent-id
- menu-item-position
- menu-item-type
- menu-item-title
- menu-item-url
- menu-item-description
- menu-item-attr-title
- menu-item-target
- menu-item-classes
- menu-item-xfn
- menu-item-status
Думаю, из названий, понятно какой за что отвечает.
После выполнения функция возвращает false в случае неудачи, либо int с ID элемента меню(?) если всё прошло успешно.
Итак, нам нужно создать подменю с ссылкой на категорию для уже существующего элемента, если категория не пуста. Давайте приступим.
/**
* myDynamicMenu
* @param integer $parent - ID родительской категории
* @param string $itemName - имя элемента меню
* @return boolean
*/
function myDynamicMenu($parent, $itemName)
{
// $children - массив с потомками категории $parent.
// Сюда попадают только те потомки, которые имеют хотя бы одну запись.
$children = get_categories(array('child_of' => $parent, ));
// Получаем массив всех меню с их именем и ID в виде name => id
$locations = get_nav_menu_locations();
// Выбираем нужное нам меню по ID
$items = wp_get_nav_menu_items($locations['header']);
// В будущем сюда будет записан ID пункта меню, для которого мы будем создавать
// подменю
$parentMenuId = 0;
// В будущем будет массив со всеми пунктами меню, чтоб избежать повтора.
$titles = array();
// Начинаем работу с массивом всех элементов меню
foreach($items as $item)
{
// Записываем имя, чтоб в будущем избежать повтора
$titles[] = $item->title;
// Если совпадает искомым именем, то запишем его ID
if($item->title == $itemName)
{
$parentMenuId = $item->ID;
}
}
// Начинаем работу с нашими категориями
foreach($children as $child)
{
// Если был найден нужный элемент меню и категория ещё не добавлена в меню
if($parentMenuId != 0 && !in_array($child->cat_name, $titles))
{
// Добавляем её в меню
$add = wp_update_nav_menu_item($locations['header'], 0,
array(
'menu-item-type' => 'custom',
'menu-item-url' => '/?cat=' . $child->cat_ID,
'menu-item-title' => $child->cat_name,
'menu-item-parent-id' => $parentMenuId
)
);
}
if(!$add)
{
return false;
}
else
{
return true;
}
}
}
Далее дело за малым — ставим экшн на эту функцию и после того, как в какой-нибудь из дочерних рубрик появится хотя-бы один пост, она будет автоматически добавлена в меню, НО, сразу там не появится. Это оказалось для меня приятный плюсом. По-умолчанию администратору нужно будет подтвердить наличие этого элемента в меню, после чего оно будет принято в общий список.
Спасибо за внимание.
Возможно для людей, которые давно работают с WP я не показал ничего нового, но для новичков, вроде меня, это будет полезно знать.
Автор: kovalevsky