Есть ли способ получить элементы навигационного меню как многомерный массив вместо плоского массива?
Под древовидной структурой я подразумеваю что-то, что сохраняло бы отношения между дочерними и родительскими элементами, вот так (это всего лишь пример)…
array(
array(
'post_type' => 'page',
'post_name' => 'Home',
'children' => array()
),
array(
'post_type' => 'page',
'post_name' => 'About Us',
'children' => array(
array(
'post_type' => 'page',
'post_name' => 'Our History',
'children' => array()
)
)
)
)
Есть wp_get_nav_menu_items()
функция, но она возвращает одномерный массив со всеми элементами на одном уровне, а это не то, что мне нужно. Есть ли в WordPress встроенный способ получения многомерного массива для моих пунктов меню? Если нет, то как лучше всего wp_get_nav_menu_items()
в виде древовидной структуры превратить в многомерный массив с точки зрения производительности?
Walker
Класс обрабатывает глубину отсортированных элементов меню навигации автоматически, даже если массив является плоским.Ответы:
Проблема построения дерева из плоского массива была решена здесь с этим, слегка модифицирована, рекурсивное решение:
где мы добавили префикс
wpse_children
атрибут, чтобы избежать конфликта имен.Теперь нам осталось только определить простую вспомогательную функцию:
Теперь становится очень легко преобразовать навигационное меню в его древовидную структуру с помощью:
Для JSON мы можем просто использовать:
Для немного другой версии, где мы выбрали атрибуты, ознакомьтесь с первой версией этого ответа здесь .
Обновление: класс Уокера
Вот довольно схематичная идея, как мы можем попытаться подключиться к рекурсивной части
display_element()
метода абстрактногоWalker
класса.где
WPSE_Nav_Menu_Tree
расширениеWalker_Nav_Menu
класса:Это может дать нам альтернативный подход, если он работает.
источник
wp_get_nav_menu_items
повторяется.Вкратце, функция ниже создает дерево объектов, помещая потомки в новое свойство children внутри родительского объекта.
Код:
Применение:
Вывод:
источник
Модифицированная версия принятого ответа, в которой учитывается
menu_order
свойство пунктов меню для сохранения правильного порядка исходного плоского массива.menu_order
устанавливается автоматически WordPress, поэтому нет необходимости проверять что-либо:Применение:
источник
Здесь может быть неправильное понимание элементов навигации WordPress как древовидных структур.
Древовидные структуры в WordPress не являются многомерными массивами!
Обратите внимание, что хотя возвращенный массив пунктов меню является плоским, он все еще является древовидной структурой, поскольку каждый элемент содержит информацию о своем происхождении (родительское значение равно 0, если у элемента нет родителя, или идентификатор родительского элемента, если он делает).
Когда вы передаете такой массив в
Walker
класс, он просматривает результаты и создает два массива - один, содержащий элементы верхнего уровня, и другой, содержащий дочерние элементы в формате$parent_id => array()
где массив содержит элементы меню, которые являются прямыми этого элемента.Затем обходчик просматривает массив элементов верхнего уровня, обрабатывает этот элемент и затем проверяет массив дочерних элементов, чтобы узнать, есть ли какие-либо дочерние элементы для текущего элемента, и обрабатывает каждый из них одинаково, рекурсивно.
Если вы хотите узнать, как преобразовать древовидную структуру WordPress в многомерный массив, это совершенно другой вопрос (а не вопрос WordPress). Но информация, возвращаемая
wp_get_nav_menu_items()
это древовидная структура ... и вы можете использоватьWalker
как есть , чтобы справиться с этим.Если вы хотите увидеть точный код, который выполняет класс Walker WordPress для обхода массива, взгляните на Walker-> walk () на WordPress Trac из строк 213-258. . Вы можете использовать этот код «как есть» для построения многомерного массива, если это то, что вам нужно.
Ходоки
WordPress предназначен для использования
Walker
класса для обработки его древовидных структур. Если вы просто визуализируете меню или действительно нуждаетесь в конечном результате, вы можете рассмотреть возможность использованияwp_nav_menu()
для вывода своего меню…Пример:
Вы бы расширили класс Walker (например
Your_Walker()
), чтобы получить любой вывод, который вам нужен. Для примера, смотрите эту запись в Кодексе .источник
$sorted_menu_items
это все еще «плоский» массив, а выводом опции B является строка.wp_get_nav_menu_items()
возвращает древовидную структуру, то есть массив, в котором каждый элемент содержит данные о происхождении. Эти структуры предназначены для визуализации с помощьюWalker
класса. Если в данном случае просто используется преобразование «плоского» массива в многомерный массив на основе данных о происхождении (например'post_parent' => 123
), этот вопрос технически не относится к WordPress и должен быть перенесен в переполнение стека.