Как вывести меню по конкретному иерархическому типу
Материал из Umicms
Актуально для версии 2.9.5
Задача
Если Вы столкнулись с данной задачей, то решить её стандартными средствами нельзя. Необходимо написать кастомный макрос, на основе content menu и его служебных методов.
Решение
%custom custom_menu()% — выводит меню
Все параметры в нем идентичны параметрам content menu, только добавляется параметр $h_type_id
$h_type_id
Идентификатор иерархического типа, страницы которого будут выведены в меню. Список иерархических типов можно посмотреть настройках модуля "Шаблоны данных".
Для применения этого макроса скопируйте код макроса в файл /classes/modules/content/__custom.php, также не забудьте добавить пермишены.
Код макроса
public function custom_menu($menu_tpl = "default", $max_depth = 1, $pid = false, $h_type_id = false) {
$cmsController = cmsController::getInstance();
$hierarchy = umiHierarchy::getInstance();
if($pid) {
if(!is_numeric($pid)) {
$pid = $hierarchy->getIdByPath($pid);
}
$parent_alt = $hierarchy->getPathById($pid, false, true, false, true);
} else {
$pid = 0;
$parent_alt = $cmsController->pre_lang ."/". $cmsController->getUrlPrefix();
}
if($parent_alt) {
$parent_alt = rtrim($parent_alt, '/');
}
$h_type_id = preg_replace('/\s/', '', $h_type_id);
$templates = def_module::loadTemplates("content/menu/" . $menu_tpl);
return content::build_cat_menu($pid, $templates, 0, $parent_alt, $max_depth, $h_type_id);
}
public function getCatMenuTemplates($templates, $curr_depth) {
$suffix = "_level" . $curr_depth;
$block = getArrayKey($templates, "menu_block" . $suffix);
$line = getArrayKey($templates, "menu_line" . $suffix);
$line_a = (array_key_exists("menu_line" . $suffix . "_a", $templates)) ? $templates["menu_line" . $suffix . "_a"] : $line;
$line_in = (array_key_exists("menu_line" . $suffix . "_in", $templates)) ? $templates["menu_line" . $suffix . "_in"] : $line;
$class = getArrayKey($templates, "menu_class" . $suffix . "");
$class_last = getArrayKey($templates, "menu_class" . $suffix . "_last");
if(!$block) {
switch($curr_depth) {
case 1: $suffix = "_fl"; break;
case 2: $suffix = "_sl"; break;
}
$block = getArrayKey($templates, 'menu_block' . $suffix);
$line = getArrayKey($templates, 'menu_line' . $suffix);
$line_a = (array_key_exists("menu_line" . $suffix . "_a", $templates)) ? $templates["menu_line" . $suffix . "_a"] : $line;
$line_in = (array_key_exists("menu_line" . $suffix . "_in", $templates)) ? $templates["menu_line" . $suffix . "_in"] : $line;
}
if(!($separator = getArrayKey($templates, 'separator' . $suffix))) {
$separator = getArrayKey($templates, 'separator');
}
if(!($separator_last = getArrayKey($templates, 'separator_last' . $suffix))) {
$separator_last = getArrayKey($templates, 'separator_last');
}
return array($block, $line, $line_a, $line_in, $separator, $separator_last, $class, $class_last);
}
public function build_cat_menu($page_id, &$templates, $curr_depth = 0, $parent_alt_name = "/", $max_depth = 1, $h_type_id = false) {
static $childsCache = array();
$hierarchy = umiHierarchy::getInstance();
$cmsController = cmsController::getInstance();
$config = mainConfiguration::getInstance();
list(
$template_block, $template_line, $template_line_a, $template_line_in, $separator, $separator_last, $class, $class_last
) = content::getCatMenuTemplates($templates, ($curr_depth + 1));
if(isset($childsCache[$page_id])) {
$result = $childsCache[$page_id];
} else {
$allow_visible = false;
$langId = false;
if($page_id) {
$parentElement = $hierarchy->getElement($page_id);
if (! ($parentElement instanceOf umiHierarchyElement)) {
return false;
}
$langId = $parentElement->getLangId();
}
$h_type_id = intval($h_type_id);
$childs = $hierarchy->getChilds($page_id, false, $allow_visible, 1, $h_type_id, false, $langId);
if($childs === false) $childs = array();
$result = array_keys($childs);
$childsCache[$page_id] = $result;
}
$sz = sizeof($result);
if($sz == 0) {
return "";
}
$lines = array();
$arr_lines = array();
$c = 0;
$currentElementId = $cmsController->getCurrentElementId();
$allParents = $hierarchy->getAllParents($currentElementId, true);
foreach($result as $element_id) {
$element = $hierarchy->getElement($element_id);
if (!$element) continue;
$text = $element->getName();
$link = $rawLink = $parent_alt_name . '/' . $element->getAltName();
if ($config->get('seo', 'url-suffix.add')) {
$link .= $config->get('seo', 'url-suffix');
}
if($template_line_in && $template_line_in != $template_line) {
if ($max_depth > 1 && content::isInPath($element_id, $templates, ($curr_depth + 1), $link, $max_depth - 1)) {
$is_active = true;
$line = $template_line_in;
} else {
$is_active = (in_array($element_id, $allParents) !== false);
$line = ($is_active) ? $template_line_a : $template_line;
}
} else {
$is_active = (in_array($element_id, $allParents) !== false);
$line = ($is_active) ? $template_line_a : $template_line;
}
$sub_menu = '';
if(strstr($line, "%sub_menu%") && $max_depth > 1) {
if($element->getValue("show_submenu") && ($is_active || $element->getValue("is_expanded"))) {
$sub_menu = content::build_cat_menu($element_id, $templates, ($curr_depth + 1), $rawLink, $max_depth - 1, $h_type_id);
}
}
if($element->getIsDefault()) {
$link = $element->link;
}
$item_arr = array();
$item_arr['@id'] = $element_id;
$item_arr['@link'] = $link;
$item_arr['@name'] = $text;
$item_arr['@alt-name'] = $element->getAltName();
$item_arr['xlink:href'] = "upage://" . $element_id;
if (def_module::isXSLTResultMode()) {
if($max_depth > 1 && XSLT_NESTED_MENU && $element->getValue("show_submenu") && ($is_active || $element->getValue("is_expanded"))) {
$xslt_submenu = content::build_cat_menu($element_id, $templates, ($curr_depth + 1), $rawLink, $max_depth - 1, $h_type_id);
if(is_array($xslt_submenu) && isset($xslt_submenu['items'], $xslt_submenu['items']['nodes:item']) && sizeof($xslt_submenu['items']['nodes:item'])) {
$item_arr['items']['nodes:item'] = $xslt_submenu['items']['nodes:item'];
}
}
}
if(XSLT_NESTED_MENU != 2) {
$item_arr['node:text'] = $text;
}
$item_arr['void:num'] = ($c+1);
$item_arr['void:sub_menu'] = $sub_menu;
$item_arr['void:separator'] = (($sz == ($c + 1)) && $separator_last) ? $separator_last : $separator;
if($is_active) {
$item_arr['attribute:status'] = "active";
}
$item_arr['class'] = ($sz > ($c + 1)) ? $class : $class_last;
$arr_lines[] = def_module::parseTemplate($line, $item_arr, $element_id);
$c++;
$hierarchy->unloadElement($element_id);
}
$block_arr = array(
'subnodes:items' => $arr_lines,
'void:lines' => $arr_lines,
'id' => $page_id
);
return def_module::parseTemplate($template_block, $block_arr, $page_id);
}