Вывод данных компонентами

Для типового вывода записей Highload-блока в публичной части сайта используйте стандартные компоненты:

  • bitrix:highloadblock.list — выбирает несколько записей, применяет фильтр, сортировку и постраничную навигацию.

  • bitrix:highloadblock.view — получает одну запись по идентификатору или другому полю.

Используйте стандартные компоненты, когда нужен типовой вывод данных без собственной логики запроса. Если странице нужна сложная выборка, объединение связанных данных, кеширование результата или отдельная модель доступа, получите записи через динамический ORM-класс по статье Работа с записями и передайте подготовленный результат в собственный компонент.

Перед подключением компонентов создайте Highload-блок, добавьте пользовательские поля и записи. Подключите пролог на публичной странице, чтобы инициализировать глобальный объект $APPLICATION, через который вызывают компоненты. Варианты подключения для обычной страницы и страницы без шаблона приведены в статье Жизненный цикл запроса.

Примеры шаблонов используют поля из раздела Схема данных в примерах.

Выбрать компонент

Компоненты решают разные задачи, но используют один Highload-блок и одинаковую модель проверки прав.

Задача

Компонент

Обязательные данные

Результат

Показать набор записей

bitrix:highloadblock.list

Идентификатор блока

Список с фильтрацией, сортировкой и постраничной навигацией

Показать одну запись

bitrix:highloadblock.view

Идентификатор блока, поле поиска и его значение

Поля найденной записи

Компоненты предназначены только для чтения. Добавляйте, изменяйте и удаляйте записи через динамический 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',
    ]
);

Пустая строка во втором аргументе выбирает шаблон компонента по умолчанию.

Настроить параметры списка

Компонент поддерживает следующие параметры.

Обязательные параметры отмечены *

Параметр

Тип

Описание

BLOCK_ID*

int

Идентификатор Highload-блока. Без него компонент выводит ошибку и прекращает работу

DETAIL_URL

string

Шаблон ссылки на отдельную запись. Стандартный шаблон заменяет маркеры #ID# и #BLOCK_ID#

ROWS_PER_PAGE

int

Число записей на странице. По умолчанию — 0. При неположительном значении компонент выводит все найденные записи без навигации

PAGEN_ID

string

Строковый идентификатор навигации. По умолчанию — page. Используется только при положительном ROWS_PER_PAGE

FILTER_NAME

string

Имя глобальной переменной с ORM-фильтром. Недопустимое имя или значение не в формате массива компонент игнорирует

SORT_FIELD

string

Код поля сортировки. По умолчанию — ID. Пользовательское поле указывают полным кодом вида UF_NAME

SORT_ORDER

string

Направление сортировки: ASC или DESC. По умолчанию — DESC

CHECK_PERMISSIONS

string

Значение Y включает проверку правил доступа Highload-блока для текущего пользователя

Стандартный шаблон позволяет посетителю менять сортировку кликом по заголовку столбца. Для этого шаблон отправляет два параметра 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',
    ]
);

Настроить параметры детального просмотра

Компонент поддерживает следующие параметры.

Обязательные параметры отмечены *

Параметр

Тип

Описание

BLOCK_ID*

int

Идентификатор Highload-блока. В настройках визуального редактора по умолчанию используется значение BLOCK_ID из запроса

ROW_KEY

string

Поле, по которому компонент ищет запись. По умолчанию — ID. Пустое значение также заменяется на ID

ROW_ID*

Тип поля ROW_KEY

Значение поля ROW_KEY. В настройках визуального редактора по умолчанию используется значение ID из запроса. Для стандартного сценария это идентификатор записи типа int

LIST_URL

string

Адрес возврата к списку. Стандартный шаблон заменяет маркер #BLOCK_ID#

CHECK_PERMISSIONS

string

Значение Y включает проверку правил доступа блока

При подключении из 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, но формат значений различается.

Результат списка

Компонент списка передает следующие ключи:

Ключ

Содержимое

rows

Записи блока. ID остается исходным значением. Значения пользовательских полей с SHOW_IN_LIST = Y преобразованы в готовый HTML для списка; остальные поля остаются исходными значениями

fields

Метаданные пользовательских полей блока

tableColumns

Коды столбцов, которые стандартный шаблон выводит в таблице: ID и поля с SHOW_IN_LIST = Y

sort_id

Фактическое поле сортировки

sort_type

Фактическое направление ASC или DESC

nav_object

Объект Bitrix\Main\UI\PageNavigation. Ключ существует только при положительном ROWS_PER_PAGE

NAV_STRING, NAV_PARAMS, NAV_NUM

Пустые совместимые значения прежнего механизма навигации. Для нового шаблона используйте nav_object

Не применяйте 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'] ?>&amp;ID=<?= (int)$row['ID'] ?>">
                <?= $row['UF_NAME'] ?>
            </a>
        </li>
    <?php endforeach; ?>
</ul>

Компонент уже преобразовал UF_NAME через обработчик типа пользовательского поля. Используйте такой вывод только для значений из rows, подготовленных текущим компонентом.

Результат детального просмотра

Компонент детального просмотра передает:

Ключ

Содержимое

ERROR

Пустая строка при успешном запросе или текст ошибки

row

Исходные значения найденной записи, включая ID и поля UF_*. Ключ отсутствует при ошибке блока или прав и содержит false, если запись не найдена

fields

Метаданные пользовательских полей с подготовленными данными для их отображения. Ключ отсутствует при ошибке блока или прав

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

  • При запрете доступа компоненты используют то же сообщение, что и при отсутствующем блоке. По результату компонента различить эти причины нельзя.

Если приложению нужны разные ответы, выполните проверки до компонента в следующем порядке:

  1. Проверьте формат идентификаторов.

  2. Получите описание Highload-блока. При отсутствии верните 404.

  3. Проверьте операцию hl_element_read. При запрете верните 403.

  4. Получите запись через динамический ORM-класс. При отсутствии верните 404.

  5. Подключите компонент с теми же идентификаторами и 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-статус важнее дополнительного запроса. Для строгой модели доступа не проверяйте существование записи до права чтения: иначе ответ может раскрыть наличие закрытых данных.

Проверить результат

После подключения компонентов проверьте сценарии отдельно:

  1. Откройте список без фильтра и сравните число записей с данными Highload-блока.

  2. Проверьте сортировку по системному и пользовательскому полю.

  3. Примените фильтр с результатами и фильтр без совпадений.

  4. Переключите несколько страниц списка и убедитесь, что навигация сохраняет фильтр.

  5. Если на странице несколько списков, проверьте каждый PAGEN_ID независимо.

  6. Перейдите по DETAIL_URL к существующей записи и проверьте обратную ссылку LIST_URL.

  7. Повторите детальный запрос с ROW_KEY = ID и с уникальным пользовательским полем.

  8. Передайте отсутствующее значение ROW_ID и проверьте сообщение и HTTP-статус страницы.

  9. Повторите чтение от имени администратора, пользователя с hl_element_read и пользователя без доступа к операциям.

  10. Проверьте отображение строковых, файловых, множественных и связанных полей в пользовательском шаблоне.