У меня есть сайт с установкой Magento и установкой WordPress, расположенной рядом друг с другом и создающей перекрестные ссылки.
Недавно я потратил несколько часов на написание класса для установки в установку Magento, чтобыможет отображать меню WordPress как навигационное меню на сайте Magento.
Сообщения здесь были полезны, но ни одна из них не полностью объяснила структуру хранения меню WordPress.Как и многие вещи WP, он хранится в серии отношений.Вот структура:
(обратите внимание, что в этом примере предполагается префикс таблицы, если «wp _»)
- Во-первых, важно признать, что пункт меню может быть post (технически это страница, но страницы хранятся в таблице записей), категория , или это может быть пользовательская ссылка.
- Потому чтоWP поддерживает несколько меню. Сначала вы посмотрите в таблицу wp_term_taxonomy , чтобы найти термины с таксономией nav_menu.Запишите term_id из этой таблицы.
- Чтобы найти название и фрагмент меню, посетите таблицу wp_terms и найдите термин с идентификатором, указанным в шаге 2 выше.
- Перейдите в таблицу wp_term_relationships и перечислите все записи с помощью term_taxonomy_id, который соответствует term_id из шага 1. Поле object_id сообщает вам запись wp_post.id, где вы можете найти запись меню.
- Наконец, перейдите к wp_postmeta , чтобы найти множество элементов, описывающих меню.Особый интерес представляют:
- _menu_item_object - ТИП пункта меню (страница, пользовательский или категория)
- _menu_item_object_id - идентификаторфактический POST (или категория, если это категория), на которую ссылается пункт меню
- _menu_item_menu_item_parent - иерархическая родительская структура МЕНЮ (которая может отличаться от пост-родительских отношений)
- _menu_item_url - фрагмент меню (если это пользовательская ссылка пункт меню)
Примеры операторов SQL для выполнения описанной выше операции:
SELECT t.term_id
FROM wp_term_taxonomy as tax
LEFT JOIN wp_terms as t ON tax.term_id = t.term_id
WHERE taxonomy = 'nav_menu' and name like '%top%'
(ищет элемент меню с именем «Top» и получает идентификатор термина)
SELECT p.ID, p.post_title, p.post_name, p.menu_order, n.post_name as n_name, n.post_title as n_title, m.meta_value, pp.meta_value as menu_parent
FROM wp_term_relationships as txr
INNER JOIN wp_posts as p ON txr.object_id = p.ID
LEFT JOIN wp_postmeta as m ON p.ID = m.post_id
LEFT JOIN wp_postmeta as pl ON p.ID = pl.post_id AND pl.meta_key = '_menu_item_object_id'
LEFT JOIN wp_postmeta as pp ON p.ID = pp.post_id AND pp.meta_key = '_menu_item_menu_item_parent'
LEFT JOIN wp_posts as n ON pl.meta_value = n.ID
WHERE txr.term_taxonomy_id = 3 AND p.post_status='publish'
AND p.post_type = 'nav_menu_item' AND m.meta_key = '_menu_item_url'
ORDER BY p.menu_order
(загружает данные для меню на основе term_id из 3)
Обратите внимание, что этот оператор sql будет работать для страниц и пользовательских меню (у меня нет категорий, поэтому я их не включал).Загруженные данные позволят вам создать постоянную ссылку, используя siteurl из таблицы wp_options и добавив post_name в конец (технически это не получение родительской структуры, но WP правильно находит страницу / сообщение безit)
Обновление
Комментатор спросил о сборке дочерних пунктов меню с родительскими пунктами меню.Это нужно будет сделать с помощью PHP.Нечто подобное ниже сделает это для вас:
// run the query from above
$results = $wpdb->get_results('SELECT....');
// declare new variable to store "assembled" menu
$menu = array();
// loop over the items assigning children to parents
foreach( $results AS $row ) {
// assemble key bits for the menu item
$item = array(
// handles custom navigation labels
'title' => ( $row->post_title ) ? $row->post_title : $row->n_title,
// handles custom links
'permalink' => ( $row->meta_value ) ? $row->meta_value : get_permalink( $row->ID ),
// declares empty placeholder for any child items
'children' => array()
);
// if the menu item has a parent, assign as child of the parent
if ( $row->menu_parent ) {
$menu[ $row->menu_parent ][ 'children' ][] = $item;
} else {
$menu[ $row->ID ] = $item;
}
}
var_dump( $menu );
// outputs something like below:
/**
* array (size=6)
* 77 =>
* array (size=3)
* 'title' => string 'About Us' (length=8)
* 'permalink' => string 'http://www.example.com/about' (length=33)
* 'children' =>
* array (size=7)
* 0 =>
* array (size=3)
* 'title' => string 'Welcome' (length=22)
* 'permalink' => string 'http://www.example.com/welcome' (length=35)
* 'children' =>
* array (size=0)
* empty
* 1 =>
* array (size=3)
* 'title' => string 'Mission' (length=20)
* 'permalink' => string 'http://www.example.com/mission' (length=33)
* 'children' =>
* array (size=0)
* empty
* 90 =>
* array (size=3)
* 'title' => string 'Contact Us' (length=10)
* 'permalink' => string 'http://www.example.com/contact' (length=33)
* 'children' =>
* array (size=5)
* 0 =>
* array (size=3)
* 'title' => string 'Why Us' (length=12)
* 'permalink' => string 'http://www.example.com/why' (length=35)
* 'children' =>
* array (size=0)
* empty
* 1258 =>
* array (size=3)
* 'title' => string 'Login' (length=12)
* 'permalink' => string 'https://customlink.example.com/some/path/login.php' (length=82)
* 'children' =>
* array (size=0)
* empty
*/