Вывод данных компонентами
Для типового вывода записей Highload-блока в публичной части сайта используйте стандартные компоненты:
-
bitrix:highloadblock.list— выбирает несколько записей, применяет фильтр, сортировку и постраничную навигацию. -
bitrix:highloadblock.view— получает одну запись по идентификатору или другому полю.
Используйте стандартные компоненты, когда нужен типовой вывод данных без собственной логики запроса. Если странице нужна сложная выборка, объединение связанных данных, кеширование результата или отдельная модель доступа, получите записи через динамический ORM-класс по статье Работа с записями и передайте подготовленный результат в собственный компонент.
Перед подключением компонентов создайте Highload-блок, добавьте пользовательские поля и записи. Подключите пролог на публичной странице, чтобы инициализировать глобальный объект $APPLICATION, через который вызывают компоненты. Варианты подключения для обычной страницы и страницы без шаблона приведены в статье Жизненный цикл запроса.
Примеры шаблонов используют поля из раздела Схема данных в примерах.
Выбрать компонент
Компоненты решают разные задачи, но используют один Highload-блок и одинаковую модель проверки прав.
|
Задача |
Компонент |
Обязательные данные |
Результат |
|
Показать набор записей |
|
Идентификатор блока |
Список с фильтрацией, сортировкой и постраничной навигацией |
|
Показать одну запись |
|
Идентификатор блока, поле поиска и его значение |
Поля найденной записи |
Компоненты предназначены только для чтения. Добавляйте, изменяйте и удаляйте записи через динамический ORM-класс.
Компоненты не объявляют параметры CACHE_TYPE и CACHE_TIME и не кешируют результат запроса. Для часто открываемой страницы с дорогой выборкой оцените собственный компонент с управляемым кешированием.
Вывести список записей
Подключите bitrix:highloadblock.list и передайте идентификатор существующего Highload-блока.
$APPLICATION->IncludeComponent(
'bitrix:highloadblock.list',
'',
[
'BLOCK_ID' => $highloadBlockId,
'ROWS_PER_PAGE' => 20,
'SORT_FIELD' => 'ID',
'SORT_ORDER' => 'ASC',
'CHECK_PERMISSIONS' => 'Y',
]
);
Пустая строка во втором аргументе выбирает шаблон компонента по умолчанию.
Настроить параметры списка
Компонент поддерживает следующие параметры.
Обязательные параметры отмечены *
|
Параметр |
Тип |
Описание |
|
|
|
Идентификатор Highload-блока. Без него компонент выводит ошибку и прекращает работу |
|
|
|
Шаблон ссылки на отдельную запись. Стандартный шаблон заменяет маркеры |
|
|
|
Число записей на странице. По умолчанию — |
|
|
|
Строковый идентификатор навигации. По умолчанию — |
|
|
|
Имя глобальной переменной с ORM-фильтром. Недопустимое имя или значение не в формате массива компонент игнорирует |
|
|
|
Код поля сортировки. По умолчанию — |
|
|
|
Направление сортировки: |
|
|
|
Значение |
Стандартный шаблон позволяет посетителю менять сортировку кликом по заголовку столбца. Для этого шаблон отправляет два параметра HTTP-запроса, которых нет в таблице параметров компонента:
-
sort_type— переопределяетSORT_ORDERзначениемASCилиDESC. -
sort_id— может переопределить поле, еслиSORT_FIELDне содержит существующего пользовательского поля.
Отфильтровать записи
Параметр FILTER_NAME содержит не сам фильтр, а имя глобальной переменной. Имя должно:
-
начинаться с латинской буквы или знака подчеркивания,
-
содержать только латинские буквы, цифры и знаки подчеркивания.
Запишите в переменную массив условий до вызова компонента.
Пример. Выведите активные записи, название которых содержит строку из переменной $searchText:
$GLOBALS['highloadBlockFilter'] = [
'=UF_ACTIVE' => 1,
'%UF_NAME' => $searchText,
];
$APPLICATION->IncludeComponent(
'bitrix:highloadblock.list',
'',
[
'BLOCK_ID' => $highloadBlockId,
'FILTER_NAME' => 'highloadBlockFilter',
'ROWS_PER_PAGE' => 20,
'SORT_FIELD' => 'UF_NAME',
'SORT_ORDER' => 'ASC',
'CHECK_PERMISSIONS' => 'Y',
]
);
Не передавайте в фильтр необработанный массив из HTTP-запроса. Составьте разрешенный набор условий в коде страницы и приведите значения к ожидаемым типам. Правила операторов фильтра описаны в статье Выборка данных ORM.
Разместить несколько списков на странице
Постраничная навигация использует строковый идентификатор, по которому читает параметры запроса. Если на странице есть несколько компонентов списка, задайте каждому собственный PAGEN_ID.
$APPLICATION->IncludeComponent(
'bitrix:highloadblock.list',
'',
[
'BLOCK_ID' => $firstHighloadBlockId,
'ROWS_PER_PAGE' => 10,
'PAGEN_ID' => 'catalog',
'CHECK_PERMISSIONS' => 'Y',
]
);
$APPLICATION->IncludeComponent(
'bitrix:highloadblock.list',
'',
[
'BLOCK_ID' => $secondHighloadBlockId,
'ROWS_PER_PAGE' => 10,
'PAGEN_ID' => 'archive',
'CHECK_PERMISSIONS' => 'Y',
]
);
Разные идентификаторы не дают параметрам одной навигации переключать страницу другого списка. Значение PAGEN_ID по умолчанию — page. Такое же значение компонент использует, если передать пустую строку.
Вывести отдельную запись
Компонент bitrix:highloadblock.view ищет запись по полю ROW_KEY со значением ROW_ID. По умолчанию компонент использует системное поле ID.
В примере переменные $highloadBlockId и $recordId содержат идентификаторы существующих блока и записи.
$APPLICATION->IncludeComponent(
'bitrix:highloadblock.view',
'',
[
'BLOCK_ID' => $highloadBlockId,
'ROW_KEY' => 'ID',
'ROW_ID' => $recordId,
'LIST_URL' => '/directory/?BLOCK_ID=#BLOCK_ID#',
'CHECK_PERMISSIONS' => 'Y',
]
);
Настроить параметры детального просмотра
Компонент поддерживает следующие параметры.
Обязательные параметры отмечены *
|
Параметр |
Тип |
Описание |
|
|
|
Идентификатор Highload-блока. В настройках визуального редактора по умолчанию используется значение |
|
|
|
Поле, по которому компонент ищет запись. По умолчанию — |
|
|
Тип поля |
Значение поля |
|
|
|
Адрес возврата к списку. Стандартный шаблон заменяет маркер |
|
|
|
Значение |
При подключении из PHP передайте BLOCK_ID и ROW_ID в массиве параметров. Не используйте вместо них значения запроса из настроек визуального редактора. Проверяйте тип и формат входного значения до вызова компонента.
Чтобы искать по пользовательскому полю, передайте его код в ROW_KEY, а искомое значение — в ROW_ID. Поле должно существовать. Если возможны дубли, компонент вернет первую запись результата, поэтому для адреса отдельной записи используйте поле с уникальными значениями.
Связать список с детальной страницей
Создайте страницу списка /directory/index.php и детальную страницу /directory/view.php. Параметр DETAIL_URL содержит подстановочные маркеры. Компонент заменяет #ID# идентификатором записи, а #BLOCK_ID# — идентификатором Highload-блока.
$APPLICATION->IncludeComponent(
'bitrix:highloadblock.list',
'',
[
'BLOCK_ID' => $highloadBlockId,
'DETAIL_URL' => '/directory/view.php?BLOCK_ID=#BLOCK_ID#&ID=#ID#',
'ROWS_PER_PAGE' => 20,
'CHECK_PERMISSIONS' => 'Y',
]
);
В стандартном шаблоне ссылка применяется к значению столбца ID. На детальной странице приведите параметры запроса к целочисленному типу и передайте полученные идентификаторы в параметры BLOCK_ID и ROW_ID:
$highloadBlockId = (int)($_GET['BLOCK_ID'] ?? 0);
$recordId = (int)($_GET['ID'] ?? 0);
if ($highloadBlockId <= 0 || $recordId <= 0)
{
\CHTTP::SetStatus('404 Not Found');
ShowError('Запись не найдена');
return;
}
$APPLICATION->IncludeComponent(
'bitrix:highloadblock.view',
'',
[
'BLOCK_ID' => $highloadBlockId,
'ROW_KEY' => 'ID',
'ROW_ID' => $recordId,
'LIST_URL' => '/directory/',
'CHECK_PERMISSIONS' => 'Y',
]
);
Проверка перед компонентом отсекает некорректные идентификаторы. Сам компонент проверяет, существуют ли блок и запись, но не устанавливает HTTP-статус. Если приложению нужен корректный ответ 404 и для отсутствующей записи, выполните предварительную ORM-проверку по алгоритму из раздела Обработать отсутствие данных.
Для адреса по уникальному пользовательскому полю задайте ROW_KEY в детальном компоненте и сформируйте ссылку в пользовательском шаблоне списка. Стандартный DETAIL_URL заменяет только идентификаторы #ID# и #BLOCK_ID#.
Проверить права доступа
Значение CHECK_PERMISSIONS = Y включает проверку правил Highload-блока для текущего пользователя. Компонент продолжает работу, если доступна хотя бы одна операция. Администратор проходит проверку независимо от правил блока.
Параметр защищает только запрос самого компонента. Строгую проверку операции hl_element_read и прямые обращения к динамическому ORM-классу выполняйте отдельно. Модель разрешений и пример кода приведены в статье События записей и права доступа.
Использовать результат компонента
Оба компонента передают данные в шаблон через $arResult, но формат значений различается.
Результат списка
Компонент списка передает следующие ключи:
|
Ключ |
Содержимое |
|
|
Записи блока. |
|
|
Метаданные пользовательских полей блока |
|
|
Коды столбцов, которые стандартный шаблон выводит в таблице: |
|
|
Фактическое поле сортировки |
|
|
Фактическое направление |
|
|
Объект |
|
|
Пустые совместимые значения прежнего механизма навигации. Для нового шаблона используйте |
Не применяйте htmlspecialcharsbx() к подготовленному HTML отображаемого пользовательского поля. Иначе разметка типа поля появится на странице как текст. Сырые значения полей, которые не входят в tableColumns, перед выводом нужно форматировать или экранировать отдельно.
Пример template.php. Выведите идентификатор ссылкой и подготовленное значение поля UF_NAME. Поле должно иметь настройку SHOW_IN_LIST = Y.
<?php
if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true)
{
die();
}
?>
<ul>
<?php foreach ($arResult['rows'] as $row): ?>
<li>
<a href="/directory/view.php?BLOCK_ID=<?= (int)$arParams['BLOCK_ID'] ?>&ID=<?= (int)$row['ID'] ?>">
<?= $row['UF_NAME'] ?>
</a>
</li>
<?php endforeach; ?>
</ul>
Компонент уже преобразовал UF_NAME через обработчик типа пользовательского поля. Используйте такой вывод только для значений из rows, подготовленных текущим компонентом.
Результат детального просмотра
Компонент детального просмотра передает:
|
Ключ |
Содержимое |
|
|
Пустая строка при успешном запросе или текст ошибки |
|
|
Исходные значения найденной записи, включая |
|
|
Метаданные пользовательских полей с подготовленными данными для их отображения. Ключ отсутствует при ошибке блока или прав |
В отличие от результата списка, значения в row не преобразованы в HTML. Сначала проверьте ERROR, затем экранируйте простое строковое поле перед выводом. Для файлового, списочного, множественного или связанного поля используйте обработчик типа пользовательского поля, как в стандартном шаблоне.
Следующий пример рассчитан на блок, в котором существуют поля UF_NAME и UF_FILE:
<?php
if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true)
{
die();
}
if (!empty($arResult['ERROR']))
{
ShowError($arResult['ERROR']);
return;
}
global $USER_FIELD_MANAGER;
$name = htmlspecialcharsbx((string)$arResult['row']['UF_NAME']);
$fileField = $arResult['fields']['UF_FILE'];
$fileHtml = $USER_FIELD_MANAGER->getListView(
$fileField,
$arResult['row']['UF_FILE']
);
?>
<h1><?= $name ?></h1>
<div><?= $fileHtml ?></div>
Метод getListView() возвращает готовый HTML представления поля. Не экранируйте его повторно. Для другого блока замените UF_NAME и UF_FILE на коды существующих полей.
Подготовить шаблон
Не изменяйте файлы в /bitrix/components/bitrix/. Обновление продукта может заменить изменения. Скопируйте шаблон компонента в каталог /local/templates/<шаблон_сайта>/components/bitrix/<имя_компонента>/<имя_копии>/ и передайте имя копии вторым аргументом IncludeComponent().
Например, для шаблона cards компонента списка можно использовать каталог:
/local/templates/<шаблон_сайта>/components/bitrix/highloadblock.list/cards/
Подключение копии:
$APPLICATION->IncludeComponent(
'bitrix:highloadblock.list',
'cards',
[
'BLOCK_ID' => $highloadBlockId,
'ROWS_PER_PAGE' => 20,
'CHECK_PERMISSIONS' => 'Y',
]
);
Для детального компонента путь строится так же, но содержит имя highloadblock.view.
Общая структура шаблонов, файлы result_modifier.php и component_epilog.php описаны в статье Компоненты. Правила размещения CSS и JavaScript приведены в статье Работа со стилями.
Обработать отсутствие данных
Стандартные компоненты показывают ошибки, но не устанавливают HTTP-статусы.
-
Компонент списка вызывает
ShowError()и не подключает шаблон, если идентификатор блока не задан, блок не найден или проверка прав не дала ни одной операции. -
Детальный компонент записывает сообщение в
$arResult['ERROR'], подключает шаблон и выводит ошибку черезShowError(), если блок или запись не найдены либо доступ запрещен. -
При запрете доступа компоненты используют то же сообщение, что и при отсутствующем блоке. По результату компонента различить эти причины нельзя.
Если приложению нужны разные ответы, выполните проверки до компонента в следующем порядке:
-
Проверьте формат идентификаторов.
-
Получите описание Highload-блока. При отсутствии верните
404. -
Проверьте операцию
hl_element_read. При запрете верните403. -
Получите запись через динамический ORM-класс. При отсутствии верните
404. -
Подключите компонент с теми же идентификаторами и
CHECK_PERMISSIONS = Y.
Пример. Подготовьте детальную страницу для поиска по системному полю ID:
use Bitrix\Highloadblock\HighloadBlockRightsTable;
use Bitrix\Highloadblock\HighloadBlockTable;
use Bitrix\Main\Loader;
global $USER;
// Получите идентификаторы из запроса
$highloadBlockId = (int)($_GET['BLOCK_ID'] ?? 0);
$recordId = (int)($_GET['ID'] ?? 0);
// Подключите модуль highloadblock
if (!Loader::includeModule('highloadblock'))
{
throw new \RuntimeException('Не удалось подключить модуль highloadblock');
}
// Получите Highload-блок и проверьте входные данные
$highloadBlock = HighloadBlockTable::getById($highloadBlockId)->fetch();
if (!$highloadBlock || $recordId <= 0)
{
\CHTTP::SetStatus('404 Not Found');
ShowError('Запись не найдена');
return;
}
// Проверьте право чтения
$isAllowed = $USER->IsAdmin();
if (!$isAllowed)
{
$operationsByBlock = HighloadBlockRightsTable::getOperationsName([
$highloadBlockId,
]);
$operations = $operationsByBlock[$highloadBlockId] ?? [];
$isAllowed = in_array('hl_element_read', $operations, true);
}
if (!$isAllowed)
{
\CHTTP::SetStatus('403 Forbidden');
ShowError('Доступ запрещен');
return;
}
// Получите запись
$entity = HighloadBlockTable::compileEntity($highloadBlock);
$dataClass = $entity->getDataClass();
$record = $dataClass::getById($recordId)->fetch();
if (!$record)
{
\CHTTP::SetStatus('404 Not Found');
ShowError('Запись не найдена');
return;
}
// Подключите компонент детального просмотра
$APPLICATION->IncludeComponent(
'bitrix:highloadblock.view',
'',
[
'BLOCK_ID' => $highloadBlockId,
'ROW_KEY' => 'ID',
'ROW_ID' => $recordId,
'LIST_URL' => '/directory/',
'CHECK_PERMISSIONS' => 'Y',
]
);
Предварительная выборка повторяет чтение записи, которое затем выполнит компонент. Используйте ее, когда корректный HTTP-статус важнее дополнительного запроса. Для строгой модели доступа не проверяйте существование записи до права чтения: иначе ответ может раскрыть наличие закрытых данных.
Проверить результат
После подключения компонентов проверьте сценарии отдельно:
-
Откройте список без фильтра и сравните число записей с данными Highload-блока.
-
Проверьте сортировку по системному и пользовательскому полю.
-
Примените фильтр с результатами и фильтр без совпадений.
-
Переключите несколько страниц списка и убедитесь, что навигация сохраняет фильтр.
-
Если на странице несколько списков, проверьте каждый
PAGEN_IDнезависимо. -
Перейдите по
DETAIL_URLк существующей записи и проверьте обратную ссылкуLIST_URL. -
Повторите детальный запрос с
ROW_KEY = IDи с уникальным пользовательским полем. -
Передайте отсутствующее значение
ROW_IDи проверьте сообщение и HTTP-статус страницы. -
Повторите чтение от имени администратора, пользователя с
hl_element_readи пользователя без доступа к операциям. -
Проверьте отображение строковых, файловых, множественных и связанных полей в пользовательском шаблоне.