Класс для создания древовидного меню навигации.
$blockInfo — параметры блока навигации. Это массив с двумя обязательными элементами ['src-block-id'=>..., 'tpl'=>...]
, в качестве значений которых берутся, соответственно, номер исходного блока и имя шаблона.
Этот массив можно получить с помощью метода Blox::getBlockInfo().
Познакомимся с параметрами метода Nav::init() на примере:
shop/nav.tpl
<?php
// *.tpl
Nav::init(
$blockInfo,
$tab,
[//$fields
'name' => 4, // Поле для названия пункта меню
'parent-id' => 2, // Поле для номера записи родительского пункта
// Необязательные поля
'alt-headline' => 5, // Поле для альтернативного заголовка целевой страницы
'alt-url' => 6, // Поле для произвольного URL, который будет перебивать штатный URL
'num-of-higher-levels'=> 7, // Поле для количества вышестоящих уровней, которые будут показаны, когда выбран текущий пункт меню
'num-of-items' => 8, // Поле, где будет сохраняться количество записей целевого блока, соответствующих данному пункту навигации (not null default 0)
'file' => 9, // Поле для файла (как правило, для фотоиконки в режиме галереи)
],
[//$options
'target-block-id' => $xdat[1], // Номер целевого блока к которому идет запрос из меню
'target-field' => $xdat[2], // Номер поля в целевом блоке, где хранится rec-id пункта навигации
// Необязательные опции
'target-page-id' => $xdat[7], // Номер страницы с целевым блоком.
'target-tpl' => $xdat[3], // Шаблон целевого блока к которому идет запрос из меню
'initial-headline' => $xdat[4], // Заголовок вводной страницы (когда ни один пункт меню не выбран)
'hide-non-active'=> $xdat[5], // Не выводить неактивные ветки
'show-empty-branches'=> $xdat[6], // Выводить ветки без товаров
'items-pick' => 'pick[3][ne]=1', // Дополнительный pick-запрос к целевому блоку при подсчете numOfItems.
// В том случае, если данная опция не применяется, по умолчанию все же сработает одно условие —
// не будут подсчитаны скрытые записи, что равноценно примененному здесь запросу pick[3][ne]=1.
// Синтаксис pick-запросов.
]
);
<?php
$titles = [
2 => 'Родительская категория',
3 => 'Скрыть пункт списка',
4 => 'Название пункта списка (а также заголовок целевой страницы)',
5 => 'Альтернативный заголовок целевой страницы',
6 => 'Поставить на этот пункт списка произвольный URL',
7 => 'Сколько вышестоящих уровней данного пункта показывать в режиме "Список"',
8 => 'Количество нескрытых товаров во всей категории',
9 => 'Фотоиконка для режима "Галерея"',
];
$types = [
2 => 'select template(menu) edit(4) output(rec)',
3 => 'tinyint(1) unsigned not null default 0',
4 => 'varchar(332)',
5 => 'varchar(332)',
6 => 'varchar(332)',
7 => 'tinyint(4) unsigned not null default 22',
8 => 'mediumint not null default 0',
9 => 'file thumbnail(crop, 200,200) destination(datafiles/shop/nav)',
];
$params = [
'multi-record' => true,
];
$xtitles = [
1 => 'Номер исходного товарного блока к которому идет запрос (src-block-id)',
2 => 'Номер поля товарного блока, где хранится rec-id пункта навигации',
3 => 'Шаблон целевого блока к которому идет запрос из меню',
4 => 'Заголовок вводной страницы (когда ни один пункт меню не выбран)',
5 => 'Не выводить неактивные ветки',
6 => 'Показать категории без товаров',
];
$xtypes = [
1 => 'mediumint unsigned',
2 => 'tinyint(4) unsigned',
3 => 'varchar(128)',
4 => 'varchar(332)',
5 => 'tinyint(1) unsigned not null default 0',
6 => 'tinyint(1) unsigned not null default 0',
];
Предварительно в любом месте должно быть инициализировано древо навигации с помощью Nav::init(...).
Структура возвращаемого массива
[
[ // Первый элемент меню первого уровня
'href' => 'elektroinstrumenty/', // URL пункта меню
'name' => 'Электроинструменты', // Текст (название) пункта меню
'active' => true, // Пункт является активным (выбранным)
'num-of-items' => 100, // количество записей целевого блока, соответствующих данному пункту навигации
'children' => [ // Пункты более низкого уровня (подменю)
[
'href' => 'dreli/',
'name' => 'Дрели',
'active' => true,
'num-of-items' => 99,
'children' => [...]
],
...
]
],
...
]
Данные, полученные с помощью метода Nav::getNodes() используются для построения непосредственного html-кода навигации.
В общем случае придется написать собственную рекурсивную функцию для разбора многомерных массивов, полученный с помощью метода Nav::getNodes().
Для построения простого многоуровневого меню можно воспользоваться методом Nav::getList() .
Пример рекурсивной функции (menu.tpl)
<?php Nav::init(...); //См. выше $nodes = Nav::getNodes($blockInfo['src-block-id']); // Массив $nodes непосредственно для вывода кода навигации не пригоден. // Необходимо написать рекурсивную функцию для разбора этого многомерного массива. if (!function_exists('getNodes2')) { function getNodes2($nodes) { if ($nodes) { $htm = '<ul>'; foreach ($nodes as $node) { # Количество записей в данной категории $numOfItemsHtm = ($node['num-of-items']) ? ' <span class="badge">'.$node['num-of-items'].'</span>' : '' ; $htm.= ' <li'.($node['active'] ? ' class="active"' : '').'> <a href="'.$node['href'].'">'.$node['name'].$numOfItemsHtm.'</a> '.getNodes2($node['children']).' </li>'; } $htm.= '</ul>'; } return $htm; } } echo' <nav> '.getNodes2($nodes).' </nav>';
Метод для получения html-кода простого многоуровневого списка.
Пример использования метода (menu.tpl)
<?php Nav::init($blockInfo, ...); //См. выше echo' <nav> '.Nav::getlist( Nav::getNodes($blockInfo['src-block-id']) ).' </nav>';
Метод дает всю информацию о древе навигации. Предварительно в любом месте должно быть инициализировано древо навигации с помощью Nav::init(...).
Возвращает многомерный массив.
$keys — последовательность ключей в виде массива, где начальный элемент соответствует номеру навигационного блока. Подробности о массиве $keys читайте в описании метода Arr::getByKeys().
Примеры
Nav::get([$blockInfo['src-block-id']]) - Получить всю информацию о текущем меню навигации
Nav::get([$blockInfo['src-block-id','ancestors',0]]) - Получить ID навигации самого верхнего уровня для текущего состояния
Nav::get([$blockInfo['src-block-id'], 'children', 0]) - Получить номера пунктов первого уровня
Полную картину о всех активных блоках навигации можно получить из примера, приведенного ниже, где аргумент вообще опущен.
Nav::get() возвращает:
<?php
[
19 => [// Номер блока навигации
'active-nav-id' => 2,
'target-page-id' => 2, // Номер целевой страницы
'block-info' => [
'id' => 198,
'tpl' => 'shop/nav',
'delegated-id' => 0,
'parent-block-id' => 18,
'parent-rec-id' => 1,
'src-block-id' => 198,
],
'fields' => [
'name' => 4,
'parent-id' => 2,
'alt-headline' => 5,
'alt-url' => 6,
'num-of-higher-levels' => 7,
'num-of-items' => 8,
'file' => 9
],
'options' => [
'target-block-id' => 27,
'target-field' => 2,
'hide-non-active' => false,
'show-empty-branches'=> false,
'initial-headline' => ,
],
'records' => [ // Все записи блока
1 => [ // Номер записи
'name' => 'Электроинструменты',
'parent-id' => 0,
'alt-headline' => '',
'alt-url' => '',
'num-of-higher-levels' => 22, // Число показанных предков
'file' => 'elektroinstrumenty.png',
'num-of-items' => 0,
'href' => '?page=2&block=201&p[2]=1',
'rec' => 1, // все данные записи, как в переменной $dat
1 => ...
2 => ...
],
...
],
'new-rec' => [
'edit' => '...'// Код кнопки редактирования новой записи,
'edit-href' => '?edit&block=19&rec=new...' // URL кнопки редактирования новой записи,
],
'children' => [
0 => [1,3,5,8], // Номера пунктов и номера их детей
1 => [2],
],
'ancestors' => [5,3,1], // Цепочка предков активного (выбранного) пункта меню, начиная с родителя и далее к старшим (их ID)
'adjacents' => [ // Только для последнего уровня
['prev'] => 3,
['next'] => 5
]
]
]
Сбрасывает данные о количестве записей (numOfItems) целевого блока, приходящиеся на каждый пункт навигации. В последующем эти данные автоматически обновятся.
$blockInfo — параметры блока навигации. Это массив с двумя элементами ['src-block-id'=>..., 'tpl'=>...]
, в качестве значений которых берутся, соответственно, номер исходного блока и имя шаблона.
Достаточно использовать один из элементов массива, предпочтительно src-block-id. При использовании только элемента tpl, обновятся все блоки с этим шаблоном.
Этот метод необходимо применять при каждом изменении числа записей в целевом блоке только в операционной системе Windows , в Linux обновление производится автоматически.
Внимательно выбирайте момент сброса данных, так как ненужные вызовы метода приведут к замедлению вывода навигации. Обычно метод вызывается в предобработчике обновления данных (.tuh).
Пример:
Nav::resetNumOfItems(['tpl'=>'shop/nav']);
Блок навигации, построенный на класса Nav, генерирует ссылки на псевдостраницы с запросами к одному (целевому) блоку. Однако, на этих псевдостраницах можно разместить и другие блоки. привязав их записи к url псевдостраниц с помощью метода Tdd::bind().
Если блоки на целевой странице используют только привязку к URL, то в опциях метода Nav::init() можно указывать любой номер поля (target-field) и несуществующий номер блока (target-block-id). Однако, если вы сделегируете меню на другую страницу, то система не сможет по неправильному блоку определить страницу каталога. В этом случае применяйте еще и номер целевой страницы (target-page-id).