parser

Написать ответ на текущее сообщение

 

 
   команды управления поиском

Ответ

sly 17.08.2004 16:52

Не, они накапливаются. Или я что-то не так делал. Но пробовал так сразу. А теперь посмотрел 32 раз на "Построение деревьев" твое и написал пару методов + заюзал хэш. Теперь все работает, но ты наверняка упростил бы...

Кароче, вот что вышло:
##############################
# 16:33 13/08/2004 sly
# Основано на TNavigation от Sumo
##############################

@CLASS
TNavigationDB

##############################
# Запускаем
@Init[]
$sitename[$env:SERVER_NAME]
$root[^GetSectionsByParent[0]]	^rem{ *** Корневые *** }
$roll[^Roll[]]
$temptable[^table::sql{
	SELECT
		id,
		pid,
		uri,
		title,
		is_published,
		is_admin
	FROM
		sections
}]
$hashTree[^CreateHashTree[$temptable;pid]]

##############################
# Хэш для ускорения поиска
@CreateHashTree[messages;field]
$result[^messages.hash[$field][$.distinct[tables]]]

##############################
# Сдвиг для urisplit. Поэтому система будет работать не только в корне сайта
@Roll[]
$urisplit[^MAIN:ENGINE.ROOT.lsplit[/]]
$result[^urisplit.count[]]

##############################
# Счетчик вложенных секций у указанного родителя
@SectionsCount[pid][tempsection;count]
# Вычисляем количество записей
$count(0)
$tempsection[^GetSectionsByParent[$pid]]
^tempsection.menu{
	^if($tempsection.is_published){$count($count+1)}
}
$result[$count]

##############################
# Возвращает таблицу секций-детей. Возможен лимит
@GetSectionsByParent[pid;limit]
$result[^table::sql{
	SELECT
		id,
		pid,
		uri,
		title,
		is_published,
		is_admin
	FROM
		sections
	WHERE
		^if(def $pid){pid = ^pid.int(0) AND}
		is_published = 1
}[^if(^limit.int(0)){$.limit(^limit.int(0))}]]
   
##############################
# "Хлебные крошки"
@BreadCrops[]
# Роемся в подразделах, чтобы выцепить текущий. После этого кидаем крошки
# Инициализируем secondnav и записываем в него главную страницу
$self.secondnav[^table::create{uri	title}]
^self.secondnav.append{$MAIN:ENGINE.ROOT	$sitename}
# Разбираем uri
$uri[$request:uri ]
$urisplit[^uri.lsplit[/]]
# Проходим по urisplit
^urisplit.menu{
	^if((^urisplit.line[] > $roll) && (^urisplit.line[] < $urisplit)){
		^if(^urisplit.line[] == 1+$roll){
			^if(^root.locate[uri;$urisplit.piece/]){
				$currentid[$root.id]
				^secondnav.append{^if(^urisplit.line[] != ($urisplit - 1)){${MAIN:ENGINE.ROOT}$root.uri}	^taint[as-is][$root.title]}
			}         
			$currenturi[$root.uri]
		}{			
			$tempsection[^GetSectionsByParent[$currentid]]
			^if(^tempsection.locate[uri;$urisplit.piece/]){
				$currentid[$tempsection.id]
				^secondnav.append{^if(^urisplit.line[] != ($urisplit - 1)){${MAIN:ENGINE.ROOT}${currenturi}$tempsection.uri}	^taint[as-is][$tempsection.title]}
			}
			$currenturi[${currenturi}$urisplit.piece/]
		}
	}
}
^secondnav.menu{
	^if(def $secondnav.uri){
		<a href="$secondnav.uri" class=secondnav>^taint[as-is][$secondnav.title]</a>
	}{
		<b>^taint[as-is][$secondnav.title]</b>
	}
}[&nbsp^;>&nbsp^;]

##############################
# Корневая навигация. Вынесено для удобства (обычно на всех страницах присутствует)
@ShowRoot[]
^root.menu{
	^if($root.is_published){
		^if($root.uri eq $request:uri){
			<a href="${MAIN:ENGINE.ROOT}$root.uri"><b>^taint[as-is][$root.title]</b></a>
		}{
			<a href="${MAIN:ENGINE.ROOT}$root.uri">^taint[as-is][$root.title]</a>
		}
	}  
}

##############################
# Подразделы
@ShowSecondNav[][tempsection]
^if($request:uri ne $MAIN:ENGINE.ROOT){
# Разбираем uri
$uri[$request:uri ]
$urisplit[^uri.lsplit[/]]
# Проходим по urisplit, чтобы вычислить id текущей секции
^urisplit.menu{
	^if((^urisplit.line[] > $roll) && (^urisplit.line[] < $urisplit)){
		^if(^urisplit.line[] == 1+$roll){
			^if(^root.locate[uri;$urisplit.piece/]){
				$currentid[$root.id]
			}         
			$currenturi[$root.uri]
		}{
			$tempsection[^GetSectionsByParent[$currentid]]
			^if(^tempsection.locate[uri;$urisplit.piece/]){
					$currentid[$tempsection.id]
			}
			$currenturi[${currenturi}$urisplit.piece/]
		}
	}
}
$tempsection[^GetSectionsByParent[$currentid]]
^tempsection.menu{
	^if($tempsection.is_published){
		^if($tempsection.uri eq $request:uri){
			<a href="$tempsection.uri"><b>^taint[as-is][$tempsection.title]</b></a>
		}{
			<a href="$tempsection.uri">^taint[as-is][$tempsection.title]</a>
		}
	} 	
}[<br>]
}

##############################
# Дерево. Будет в XML. Рекурсия (метод вызывает сам себя)
@ShowSectionsByParent[pid][tempsection]
<ul>
^if($hashTree.[$pid]){
	$tempsection[$hashTree.[$pid]]
	^tempsection.menu{
		^PrintTreeItem[$tempsection.fields;^if($hashTree.[$tempsection.id]){^ShowSectionsByParent[$tempsection.id]}]
	}
}
</ul>


##############################
# Пририсовать ветку
@PrintTreeItem[tempsection;child]
$result[<li><a href="${MAIN:ENGINE.ROOT}^GetFullPath[$tempsection.id]">$tempsection.title</a>
	^if(def $child){<ul>$child</ul>}
</li>]

##############################
# Полный путь для указанного по ID раздела
@GetFullPath[id][temp]
$hashTreeByID[^CreateHashTree[$temptable;id]]
^if($hashTreeByID.[$id]){
	$temp[$hashTreeByID.[$id]]
	^temp.menu{
		^PathPiece[$temp.fields;^if($hashTreeByID.[$temp.pid]){^GetFullPath[$temp.pid]}]
	}
}

##############################
# Возвращает постоянно наращиваемый УРЛ
@PathPiece[temp;parent]
$result[^trim[$parent]${temp.uri}]
И вопрос вдогонку: как правильней по логике-количеству отжираемой памяти я поступил с хэшами:
$hashTree - в Init[] или $hashTreeByID в GetFullPath[id]???

Вопросы, конечно, простые, но очень для меня важные - чтоб в следующий раз не спрашивать