Получение DETAIL_PAGE_URL для элемента инфоблока в D7
Проблема/контекст
В новом ядре D7 (таблица Bitrix\Iblock\ElementTable) нет готового поля DETAIL_PAGE_URL. Это связано с тем, что ссылка на детальную страницу — это динамический шаблон (например, /catalog/#SECTION_CODE#/#ELEMENT_CODE#/), который хранится в настройках инфоблока и требует подстановки реальных данных элемента для вычисления.
Решение с кодом
Чтобы получить корректную ссылку, необходимо выбрать данные элемента вместе с шаблоном URL из связанной таблицы инфоблока. Рекомендуется использовать Element API (если у инфоблока задан API_CODE), но способ также работает и с базовым ElementTable.
<?php
declare(strict_types=1);
use Bitrix\Iblock\Elements\ElementCatalogTable; // Где 'Catalog' — это API_CODE вашего инфоблока
use Bitrix\Main\Loader;
Loader::includeModule('iblock');
$elementId = 123;
// Если у инфоблока нет API_CODE, используйте \Bitrix\Iblock\ElementTable
$element = ElementCatalogTable::getList([
'select' => [
'ID',
'CODE',
'IBLOCK_SECTION_ID',
// Получаем шаблон URL из настроек инфоблока через связь IBLOCK
'DETAIL_PAGE_URL_TEMPLATE' => 'IBLOCK.DETAIL_PAGE_URL'
],
'filter' => ['=ID' => $elementId]
])->fetch();
if ($element)
{
// Метод ReplaceDetailUrl заменит плейсхолдеры типа #ID#, #CODE# на реальные значения из массива $element
$detailUrl = \CIBlock::ReplaceDetailUrl(
url: $element['DETAIL_PAGE_URL_TEMPLATE'],
arr: $element,
server_name: true,
arrType: 'E' // Тип "E" означает Element
);
echo $detailUrl;
}
Пример с использованием fetchObject()
Если вы предпочитаете работать с объектами (EO_Element), данные для замены масок нужно подготовить через метод collectValues():
$elementObject = ElementCatalogTable::getList([
'select' => ['ID', 'CODE', 'IBLOCK_SECTION_ID', 'IBLOCK.DETAIL_PAGE_URL'],
'filter' => ['=ID' => $elementId]
])->fetchObject();
if ($elementObject)
{
// ReplaceDetailUrl ожидает массив, поэтому используем collectValues()
$detailUrl = \CIBlock::ReplaceDetailUrl(
url: $elementObject->getIblock()->getDetailPageUrl(),
arr: $elementObject->collectValues(),
server_name: true,
arrType: 'E'
);
}
Параметры метода ReplaceDetailUrl
$url(string) — Шаблон URL из настроек инфоблока (например,/catalog/#SECTION_CODE#/#ELEMENT_CODE#/).$arr(array) — Массив данных элемента. Ключи должны совпадать с масками (ID для#ID#, CODE для#CODE#и т.д.).$server_name(bool) — Еслиtrue, метод подставитSITE_DIRи домен сайта. Полезно для генерации полных ссылок (в письмах или RSS).$arrType(string) — Тип сущности:"E"для элементов,"S"для разделов. Это определяет, какие маски будут обрабатываться (например,#SECTION_CODE_PATH#).
Практические детали:
- Обязательные поля: В
selectзапросаgetListнужно обязательно включать все поля, которые используются в шаблоне ссылки (обычно этоID,CODE,IBLOCK_SECTION_ID). Если в шаблоне есть#SECTION_CODE#, вам придется добавить вselectсвязь с секцией, например'SECTION_CODE' => 'IBLOCK_SECTION.CODE'. - Element API vs ElementTable: Использование
ElementCatalogTableпредпочтительнее для новых проектов, так как это дает типизацию и упрощенную работу со свойствами. Но если вы пишете универсальный код илиAPI_CODEне задан,\Bitrix\Iblock\ElementTableработает по тому же принципу. - Тип сущности: При вызове
ReplaceDetailUrlпоследний параметр'E'указывает, что мы работаем с элементом. Для разделов используется'S'.
Итог
Для получения ссылки в D7 используйте выборку шаблона через связь IBLOCK.DETAIL_PAGE_URL и стандартный метод \CIBlock::ReplaceDetailUrl для подстановки данных. Это наиболее производительный и правильный способ в рамках Bitrix Framework.
Похожие советы