Класс Nav

Класс для создания древовидного меню навигации.

Nav::init($blockInfo, $tab, $fields, $options)

Инициализирует древо навигации для заданного блока навигации.
  • $blockInfo — параметры блока навигации. Это массив с двумя обязательными элементами ['src-block-id'=>..., 'tpl'=>...], в качестве значений которых берутся, соответственно, номер исходного блока и имя шаблона. Этот массив можно получить с помощью метода Blox::getBlockInfo().

  • $tab — стандартная переменная шаблона с данными многозаписного блока.
  • $fields — массив соответствия полей шаблона полям класса.
  • $options — массив различных настроек.

Параметры метода Nav::init()

Познакомимся с параметрами метода 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::getNodes($srcBlockId, $options)

  • Возвращает многомерный древовидный массив, который используется для построения html-кода многоуровневого списка.
  • $srcBlockId — номер исходного блока навигации.
  • $options — опции. Если этому параметру задать значение 'no-edit-buttons', то кнопки редактирования перед названиями пунктов меню не выводятся.

Предварительно в любом месте должно быть инициализировано древо навигации с помощью 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>';

Nav::getList($nodes)

Метод для получения html-кода простого многоуровневого списка.

  • Возвращает html-код.
  • $nodes — массив, полученный с помощью метода Nav::getNodes().

Пример использования метода (menu.tpl)

<?php
Nav::init($blockInfo, ...); //См. выше
echo'
<nav>
    '.Nav::getlist(
        Nav::getNodes($blockInfo['src-block-id'])
    ).'
</nav>';

Nav::get($keys)

Метод дает всю информацию о древе навигации. Предварительно в любом месте должно быть инициализировано древо навигации с помощью 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
        ]
    ]
]

Nav::resetNumOfItems($blockInfo)

Сбрасывает данные о количестве записей (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).