Полезная статья Мурашова о той задаче, которую я пытался решить. Вполне рабочее решение:
Код функции:
<?php
/**
* The separate sub-menu
*
* Optional $args contents:
*
* container - Whether to wrap the ul, and what to wrap it with. Defaults to 'nav'.
* container_id - The ID that is applied to the container. Defaults to blank.
* container_class - the class that is applied to the container. Defaults to 'sub-menu-container'.
* submenu_class - CSS class to use for the ul element which forms the menu. Defaults to 'sub-menu'.
* string xpath - xPath expression.
* echo - Whether to echo the menu or return it. Defaults to echo.
*
* @author Oleg Murashov <o.murashov@gmail.com>
* @link http://omurashov.ru/wordpress/separate-output-menu-and-submenu/ Documentation
* @param array $args Arguments
* @return string|void.
*/
function get_submenu($args) {
$defaults = array(
'container' => 'nav',
'container_id' => '',
'container_class' => 'sub-menu-container',
'submenu_class' => 'sub-menu',
'submenu_id' => '',
'xpath' => "./li[contains(@class,'current-menu-item') or contains(@class,'current-menu-ancestor')]/ul",
'theme_location' => '',
'echo' => true
);
$args = wp_parse_args( $args, $defaults );
$args = (object) $args;
$menu = wp_nav_menu(
array(
'theme_location' => $args->theme_location,
'container' => '',
'echo' => false
)
);
$menu = simplexml_load_string($menu);
$submenu = $menu->xpath($args->xpath);
if (empty($submenu)) {
return;
}
// Set value of class attribute
$submenu[0]['class'] = $args->submenu_class;
// Add "id" attribute
if ($args->submenu_id) {
$submenu[0]->addAttribute('id', $args->submenu_id);
}
if ($args->container) {
$submenu_sxe = simplexml_load_string($submenu[0]->saveXML());
$sdm = dom_import_simplexml($submenu_sxe);
if ($sdm) {
$xmlDoc = new DOMDocument('1.0', 'utf-8');
$container = $xmlDoc->createElement($args->container);
// Add "class" attribute for container
if ($args->container_class) {
$container->setAttribute('class', $args->container_class);
}
// Add "id" attribute for container
if ($args->container_id) {
$container->setAttribute('id', $args->container_id);
}
$smsx = $xmlDoc->importNode($sdm, true);
$container->appendChild($smsx);
$xmlDoc->appendChild($container);
}
}
if (isset($xmlDoc)) {
$output = $xmlDoc->saveXML();
} else {
$output = $submenu[0]->saveXML();
}
if (!$args->echo) {
return $output;
}
echo $output;
}
?>
Работа с функцией очень похожа на работу с wp_nav_menu(). Параметры передаются в виде массива ключ-значение. К обязательным ключам можно условно отнести только theme_location, значение которого определяет основное меню, из которого мы будем выдергивать вложенные.
Ключ xpath позволяет определить поведение функции. По умолчанию, выбирается подменю для текущего активного пункта, если оно у него есть. Можно выбрать какое-то конкретное, передав строку вида ‘./li[contains(@class, "menu-item-99")]/ul’.
Ключ container задает тэг контейнер, но в отличии от wp_nav_menu(), где его значение может быть только div или nav, здесь можно использовать любой тэг, например section или span.
Имена остальных ключей говорят сами за себя и в комментариях, я полагаю, не нуждаются.
Пример вызова
<?php
$submenu = get_submenu(array(
'container' => 'nav',
'container_id' => 'container-sub-menu',
'container_class' => 'container-sub-menu',
'submenu_id' => 'main-sub-menu',
'submenu_class' => 'sub-menu',
'theme_location' => 'header',
'echo' => false,
));
echo $submenu;
?>
…
Источник: http://omurashov.ru/wordpress-separate-output-menu-and-submenu/
Вывод подменю отдельно от основного меню в WordPress