Как вывести меню по конкретному иерархическому типу

Материал из 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);
		}