Делаем динамическое меню в WordPress

в 16:45, , рубрики: wordpress, Веб-разработка, меню, метки: ,

Доброго времени суток.

Недавно в одном небольшом проекте на 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

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js