Битрикс. Создание комплексного компонента. Часть 4 из 4
29.09.2018
Теги: CMS • Web-разработка • Битрикс • Инфоблок • Компонент • РазделИнфоблока • ШаблонКомпонента • ЭлементИнфоблока
Исходный код нативных компонентов содержит множество переменных, назначение которых не всегда понятно. К сожалению, разработчики Битрикс не пишут комментариев, да и документация оставляет желать много лучшего. Очень часто после прочтения так называемой «документации» появляется больше вопросов, чем ответов. Здесь я постарался подробно разобрать назначение тех переменных, которые могут встретиться при чтении кода.
Чтобы упростить задачу, я разделил файл component.php
на два файла поменьше. Один подключается, когда включен режим поддержки ЧПУ, а второй — когда выключен.
<?php if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED!==true) die(); // require 'component-single.php'; if ($arParams['SEF_MODE'] == 'Y') { require 'support-sef-url.php'; // включен режим поддержки ЧПУ } else { require 'without-sef-url.php'; // не включен режим поддержки ЧПУ }
Файл local/components/tokmakov/iblock/without-sef-url.php
:
<?php /* * Файл local/components/tokmakov/iblock/without-sef-url.php */ if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED!==true) die(); /* * Если не включен режим поддержки ЧПУ */ /* * В этой переменной будем накапливать значения истинных переменных, восстанавливая их из псевдонимов. */ $arVariables = array();
Это самая «главная» переменная комплексного компонента. В конечном счете именно она будут записана в массив $arResult
— как результат работы комплексного компонента. И она будет доступна в файлах element.php
, section.php
и popular.php
, которые будут подключены, после того, как отработает component.php
.
Переменные $arComponentVariables
и $arVariableAliases
вспомогательные — они вообще не хранят значения, а лишь имена и псевдонимы. В переменной $arComponentVariables
мы указываем ключи массива $_REQUEST
, которые должны попасть в $arVariables
. В переменной $arVariableAliases
мы указываем псевдонимы для «настоящих» имен переменных.
Простой компонент iblock.element
ждет, что ему будет передан параметр ELEMENT_ID
или ELEMENT_CODE
. Простой компонент iblock.section
ждет, что ему будет передан параметр SECTION_ID
или SECTION_CODE
. Это и есть «настоящие» имена переменных, с другими переменными простые компоненты работать не умеют. Если не использовать псевдонимы, то URL страницы комплексного компонента может быть только таким
/test/index.php?SECTION_ID=28 /test/index.php?SECTION_CODE=dogs /test/index.php?ELEMENT_ID=495 /test/index.php?ELEMENT_CODE=buldog
И мы просто говорим, что надо взять значения из $_REQUEST
:
$arComponentVariables = array( 'ELEMENT_ID', 'ELEMENT_CODE', 'SECTION_ID', 'SECTION_CODE', );
Если мы хотим изменить имена переменных, мы задаем их псевдонимы.
/test/index.php?SID=28 /test/index.php?SCODE=dogs /test/index.php?EID=495 /test/index.php?ECODE=buldog
В конечном счете массив $arVariableAliases
будет таким:
$arVariableAliases = array( 'ELEMENT_ID' => 'EID', 'ELEMENT_CODE' => 'ECODE', 'SECTION_ID' => 'SID', 'SECTION_CODE' => 'SCODE' );
Но такой вид он примет не сразу, а после вызова
$arVariableAliases = CComponentEngine::MakeComponentVariableAliases( $arDefaultVariableAliases, // массив псевдонимов переменных по умолчанию $arParams['VARIABLE_ALIASES'] // массив псевдонимов из входных параметров );
А массив $arDefaultVariableAliases
мы должны задать сами — на тот случай, если $arParams['VARIABLE_ALIASES']
окажется пустым. По сути, при вызове этого метода происходит следующее:
$arVariableAliases = array_merge($arDefaultVariableAliases, $arParams['VARIABLE_ALIASES']);
При написании своих компонентов достаточно инициировать эти переменные и больше о них не вспоминать:
$arComponentVariables = array(); $arDefaultVariableAliases = array();
/* * Массив имен переменных, которые компонент может получать из запроса. Все переменные, перечисленные * в этом массиве, будут добавлены в $arVariables, если они есть в массиве $_REQUEST. Нам есть смысл * добавить в этот массив переменную ACTION, которая нам нужна, чтобы знать — какой простой компонент * нужно подключать. */ $arComponentVariables = array('ACTION');
Возможно, есть смысл еще добавить в этот массив переменные ELEMENT_ID
, ELEMENT_CODE
, SECTION_ID
, SECTION_CODE
— чтобы они гарантированно попали в $arVariables
. Наш комплексный компонент сохранит работоспособность, если по каким-то причинам $arVariableAliases
окажется пустым, см. ниже по коду вызов CComponentEngine::InitComponentVariables()
.
$arComponentVariables = array( 'ELEMENT_ID', 'ELEMENT_CODE', 'SECTION_ID', 'SECTION_CODE', 'ACTION' );
/* * Массив $arDefaultVariableAliases предназначен для задания псевдонимов «по-умолчанию» переменных в * режиме не ЧПУ. В случае, если необходимо, чтобы в HTTP запросе (в адресе страницы) переменная называлась * по другому, можно задать псевдоним этой переменной, а при работе компонента восстанавливать значение * переменной из псевдонима. Следует помнить, что псевдонимы «по-умолчанию» будут перезаписаны значениями * из массива $arParams['VARIABLE_ALIASES']. */ $arDefaultVariableAliases = array();
Возможно, есть смысл еще добавить в этот массив переменные ELEMENT_ID
, ELEMENT_CODE
, SECTION_ID
, SECTION_CODE
— чтобы они гарантированно попали в $arVariables
. Наш комплексный компонент сохранит работоспособность, если по каким-то причинам $arParams['VARIABLE_ALIASES']
окажется пустым.
$arDefaultVariableAliases = array( 'ELEMENT_ID' => 'ELEMENT_ID', 'ELEMENT_CODE' => 'ELEMENT_CODE', 'SECTION_ID' => 'SECTION_ID', 'SECTION_CODE' => 'SECTION_CODE', );
Если в визуальном редакторе не задавать псевдонимы переменных, будет сформирован такой вызов компонента:
$APPLICATION->IncludeComponent( 'tokmakov:iblock', '', array( /*...*/ 'VARIABLE_ALIASES' => array( 'ELEMENT_ID' => 'ELEMENT_ID', 'ELEMENT_CODE' => 'ELEMENT_CODE', 'SECTION_ID' => 'SECTION_ID', 'SECTION_CODE' => 'SECTION_CODE', ) /*...*/ ) );
Если в визуальном редакторе задать псевдонимы для переменных, то вызов будет таким:
$APPLICATION->IncludeComponent( 'tokmakov:iblock', '', array( /*...*/ 'VARIABLE_ALIASES' => array( 'ELEMENT_ID' => 'EID', 'ELEMENT_CODE' => 'ECODE', 'SECTION_ID' => 'SID', 'SECTION_CODE' => 'SCODE', ) /*...*/ ) );
/* * Соберем массив псевдонимов переменных из массива псевдонимов «по-умолчанию» $arDefaultVariableAliases и * массива, переданого во входных параметрах $arParams['VARIABLE_ALIASES']. По сути, происходит следующее * $arVariableAliases = array_merge($arDefaultVariableAliases, $arParams['VARIABLE_ALIASES']); */ $arVariableAliases = CComponentEngine::MakeComponentVariableAliases( $arDefaultVariableAliases, // массив псевдонимов переменных по умолчанию $arParams['VARIABLE_ALIASES'] // массив псевдонимов из входных параметров );
/* * Добавим в $arVariables переменные из $_REQUEST, которые есть в $arComponentVariables и в $arVariableAliases. * Переменные из $arComponentVariables просто добавляются в $arVariables, если они есть в $_REQUEST. Переменные * из $arVariableAliases добавляютcя под своими реальными именами, если в $_REQUEST есть соответствующий псевдоним. */ CComponentEngine::InitComponentVariables( false, // в режиме не ЧПУ всегда false $arComponentVariables, // массив имен переменных, которые компонент может получать из запроса $arVariableAliases, // массив псевдонимов переменных $arVariables // массив, в котором возвращаются восстановленные переменные );
Что происходит внутри CComponentEngine::InitComponentVariables()
:
// Если не существует $arVariables['ELEMENT_ID'], но существуют $arVariableAliases['ELEMENT_ID'] = 'EID' и // $_REQUEST['EID'] — в массив $arVariables добавляется элемент $arVariables['ELEMENT_ID'] = $_REQUEST['EID'] foreach ($arVariableAliases as $variableName => $aliasName) { if (!array_key_exists($variableName, $arVariables)) { if (is_string($aliasName) && array_key_exists($aliasName, $_REQUEST)) { $arVariables[$variableName] = $_REQUEST[$aliasName]; } } }
// Если не существует $arVariables['ELEMENT_ID'], но существуют $arComponentVariables['ELEMENT_ID'] и $_REQUEST['ELEMENT_ID'], // то в массив $arVariables добавляется элемент $arVariables['ELEMENT_ID'] = $_REQUEST['ELEMENT_ID'] if ($arComponentVariables && is_array($arComponentVariables)) { for ($i = 0; $i < count($arComponentVariables); $i++) { if (!array_key_exists($arComponentVariables[$i], $arVariables) && array_key_exists($arComponentVariables[$i], $_REQUEST)) { $arVariables[$arComponentVariables[$i]] = $_REQUEST[$arComponentVariables[$i]]; } } }
/* * Теперь определяем, какую страницу шаблона компонента нужно показать */ $componentPage = 'popular'; if (isset($arVariables['ACTION']) && $arVariables['ACTION'] == 'element') { $componentPage = 'element'; // элемент инфоблока } if (isset($arVariables['ACTION']) && $arVariables['ACTION'] == 'section') { $componentPage = 'section'; // раздел инфоблока }
/* * Обрабытываем ситуацию, когда переданы некорректные параметры SECTION_ID, SECTION_CODE, ELEMENT_ID, * ELEMENT_CODE и показываем страницу 404 Not Found */ $notFound = false; // недопустимое значение идентификатора элемента if ($componentPage == 'element') { if ($arParams['USE_CODE_INSTEAD_ID'] == 'Y') { // если используются символьные коды if ( ! (isset($arVariables['ELEMENT_CODE']) && strlen($arVariables['ELEMENT_CODE']) > 0)) { $notFound = true; } } else { // если используются идентификаторы if ( ! (isset($arVariables['ELEMENT_ID']) && ctype_digit($arVariables['ELEMENT_ID']))) { $notFound = true; } } } // недопустимое значение идентификатора раздела if ($componentPage == 'section') { if ($arParams['USE_CODE_INSTEAD_ID'] == 'Y') { // если используются символьные коды if ( ! (isset($arVariables['SECTION_CODE']) && strlen($arVariables['SECTION_CODE']) > 0)) { $notFound = true; } } else { // если используются идентификаторы if ( ! (isset($arVariables['SECTION_ID']) && ctype_digit($arVariables['SECTION_ID']))) { $notFound = true; } } } // показываем страницу 404 Not Found if ($notFound) { \Bitrix\Iblock\Component\Tools::process404( trim($arParams['MESSAGE_404']) ?: 'Элемент или раздел инфоблока не найден', true, $arParams['SET_STATUS_404'] === 'Y', $arParams['SHOW_404'] === 'Y', $arParams['FILE_404'] ); return; }
$arResult['VARIABLES'] = $arVariables; $arResult['FOLDER'] = ''; if ($arParams['USE_CODE_INSTEAD_ID'] == 'Y') { // если используются символьные коды $arResult['SECTION_URL'] = $APPLICATION->GetCurPage().'?ACTION=section'.'&'.$arVariableAliases['SECTION_CODE'].'=#SECTION_CODE#'; $arResult['ELEMENT_URL'] = $APPLICATION->GetCurPage().'?ACTION=element'.'&'.$arVariableAliases['ELEMENT_CODE'].'=#ELEMENT_CODE#'; } else { // если используются идентификаторы $arResult['SECTION_URL'] = $APPLICATION->GetCurPage().'?ACTION=section'.'&'.$arVariableAliases['SECTION_ID'].'=#SECTION_ID#'; $arResult['ELEMENT_URL'] = $APPLICATION->GetCurPage().'?ACTION=element'.'&'.$arVariableAliases['ELEMENT_ID'].'=#ELEMENT_ID#'; } $this->IncludeComponentTemplate($componentPage);
Файл local/components/tokmakov/iblock/support-sef-url.php
:
<?php /* * Файл local/components/tokmakov/iblock/support-sef-url.php */ if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED!==true) die(); /* * Если включен режим поддержки ЧПУ */ /* * В этой переменной будем накапливать значения истинных переменных, восстанавливая их из шаблонов * путей и из псевдонимов. */ $arVariables = array();
/* * Массив имен переменных, которые компонент может получать из запроса. Все переменные, перечисленные * в этом массиве, будут добавлены в $arVariables, если они есть в массиве $_REQUEST. */ $arComponentVariables = array();
Кроме переменных ELEMENT_ID
, ELEMENT_CODE
, SECTION_ID
, SECTION_CODE
могут быть переданы дополнительные переменные, например
server.com/demo/category/id/28/?sort=date&dir=desc
Переменная SECTION_ID
будет получена из сопоставления шаблона category/id/#SECTION_ID#/
. Но здесь для страницы раздела инфоблока переданы параметры сортировки списка элементов: по дате, по убыванию. Наш простой компонент iblock.section
этого делать не умеет, но это не трудно реализовать. В массиве $arComponentVariables
мы должны описать эти переменные:
$arComponentVariables = array( 'sort', 'dir' );
чтобы они были добавлены в $arVariables
и переданы дальше простому компоненту примерно так:
$APPLICATION->IncludeComponent( 'tokmakov:iblock.section', '', Array( /*...*/ // по какому полю сортировать элементы 'ELEMENT_SORT_FIELD' => $arResult['VARIABLES']['sort'], // направление сортировки — по возрастанию или убыванию 'ELEMENT_SORT_DIR' => $arResult['VARIABLES']['dir'], /*...*/ ), $component );
/* * Массив $arDefaultVariableAliases404 предназначен для задания псевдонимов переменных «по-умолчанию» * в режиме ЧПУ. В случае, если необходимо, чтобы в HTTP запросе (в адресе страницы) переменная называлась * по другому, можно задать псевдоним этой переменной, а при работе компонента восстанавливать значение * переменной из псевдонима. Следует помнить, что псевдонимы «по-умолчанию» будут перезаписаны значениями * из массива $arParams['VARIABLE_ALIASES']. */ $arDefaultVariableAliases404 = array();
Чтобы продемонстрировать использование массива $arDefaultVariableAliases404
, добавим в него элемент ELEMENT_COUNT
, который позволяет передать количество элементов инфоблока на странице при постраничной навигации:
$arDefaultVariableAliases404 = array( 'section' => array( 'ELEMENT_COUNT' => 'count', ), );
В итоге, после вызова CComponentEngine::InitComponentVariables()
ниже по коду, в массив $arVariables
будет добавлена переменная ELEMENT_COUNT
, значение которой будет получено из $_REQUEST['count']
. Мы можем передать эту переменную простому компоненту:
/* * Файл local/components/tokmakov/iblock/templates/.default/section.php */ $APPLICATION->IncludeComponent( 'tokmakov:iblock.section', '', array( /*...*/ 'ELEMENT_COUNT' => $arResult['VARIABLES']['ELEMENT_COUNT'] ?: $arParams['SECTION_ELEMENT_COUNT'], /*...*/ ), $component );
/* * Массив шаблонов путей «по-умолчанию» для работы в ЧПУ-режиме. Задает имена файлов шаблонов, которые * будут запущены в работу, если совпадет шаблон пути. Эти шаблоны путей будут перезаписаны значениями * из массива $arParams["SEF_URL_TEMPLATES"]. Массив $arDefaultUrlTemplates404 нужен исключительно на * тот случай, если по каким-либо причинам массив $arParams["SEF_URL_TEMPLATES"] окажется пустым. */ if ($arParams['USE_CODE_INSTEAD_ID'] == 'Y') { // если используются символьные коды $arDefaultUrlTemplates404 = array( 'popular' => '', 'section' => 'category/code/#SECTION_CODE#/', 'element' => 'item/code/#ELEMENT_CODE#/', ); } else { // если используются идентификаторы $arDefaultUrlTemplates404 = array( 'popular' => '', 'section' => 'category/id/#SECTION_ID#/', 'element' => 'item/id/#ELEMENT_ID#/', ); }
/* * Определим, каким в итоге будет массив шаблонов путей. По факту, происходит слияние массивов * $arUrlTemplates = array_merge($arDefaultUrlTemplates404, $arParams['SEF_URL_TEMPLATES']) */ $arUrlTemplates = CComponentEngine::MakeComponentUrlTemplates( $arDefaultUrlTemplates404, $arParams['SEF_URL_TEMPLATES'] );
/* * Соберем массив псевдонимов переменных из массива псевдонимов «по-умолчанию» $arDefaultVariableAliases404 * и массива, переданого во входных параметрах $arParams['VARIABLE_ALIASES']. По сути, происходит слияние * массивов $arVariableAliases = array_merge($arDefaultVariableAliases, $arParams['VARIABLE_ALIASES']); */ $arVariableAliases = CComponentEngine::MakeComponentVariableAliases( $arDefaultVariableAliases404, $arParams['VARIABLE_ALIASES'] );
/* * Определим файл шаблона (popular, section, element), который нужно подключить. Заодно получим значения * 1. SECTION_ID или SECTION_CODE, если запрошена страница раздела инфоблока * 2. ELEMENT_ID или ELEMENT_CODE, если запрошена страница элемента инфоблока * Переменная $arVariables передается по ссылке, поэтому на выходе будет содержать значения переменных: * server.com/demo/category/id/28/ => $arVariables = array(SECTION_ID => 28) * server.com/demo/item/id/97/ => $arVariables = array(ELEMENT_ID => 97) */ $componentPage = CComponentEngine::ParseComponentPath( $arParams['SEF_FOLDER'], $arUrlTemplates, $arVariables );
/* * Метод CComponentEngine::ParseComponentPath() не обрабатывает случай, когда шаблон пути равен пустой * строке, например 'popular' => ''. Поэтому делаем это сами */ if ($componentPage === false && parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH) == $arParams['SEF_FOLDER']) { $componentPage = 'popular'; }
// Если определить файл шаблона не удалось, показываем страницу 404 Not Found if (empty($componentPage)) { \Bitrix\Iblock\Component\Tools::process404( trim($arParams['MESSAGE_404']) ?: 'Элемент или раздел инфоблока не найден', true, $arParams['SET_STATUS_404'] === 'Y', $arParams['SHOW_404'] === 'Y', $arParams['FILE_404'] ); return; }
/* * Обрабытываем ситуацию, когда переданы некорректные параметры SECTION_ID, SECTION_CODE, ELEMENT_ID, * ELEMENT_CODE и показываем страницу 404 Not Found */ $notFound = false; // недопустимое значение идентификатора элемента if ($componentPage == 'element') { if ($arParams['USE_CODE_INSTEAD_ID'] == 'Y') { // если используются символьные коды if ( ! (isset($arVariables['ELEMENT_CODE']) && strlen($arVariables['ELEMENT_CODE']) > 0)) { $notFound = true; } } else { // если используются идентификаторы if ( ! (isset($arVariables['ELEMENT_ID']) && ctype_digit($arVariables['ELEMENT_ID']))) { $notFound = true; } } } // недопустимое значение идентификатора раздела if ($componentPage == 'section') { if ($arParams['USE_CODE_INSTEAD_ID'] == 'Y') { // если используются символьные коды if ( ! (isset($arVariables['SECTION_CODE']) && strlen($arVariables['SECTION_CODE']) > 0)) { $notFound = true; } } else { // если используются идентификаторы if ( ! (isset($arVariables['SECTION_ID']) && ctype_digit($arVariables['SECTION_ID']))) { $notFound = true; } } } // показываем страницу 404 Not Found if ($notFound) { \Bitrix\Iblock\Component\Tools::process404( trim($arParams['MESSAGE_404']) ?: 'Элемент или раздел инфоблока не найден', true, $arParams['SET_STATUS_404'] === 'Y', $arParams['SHOW_404'] === 'Y', $arParams['FILE_404'] ); return; }
/* * Добавим в $arVariables переменные из $_REQUEST, которые есть в $arComponentVariables и в $arVariableAliases. * Переменные из $arComponentVariables просто добавляются в $arVariables, если они есть в $_REQUEST. Переменные из * $arVariableAliases добавляютcя под своими реальными именами, если в $_REQUEST есть соответствующий псевдоним. */ CComponentEngine::InitComponentVariables( $componentPage, $arComponentVariables, $arVariableAliases, $arVariables );
Если были заданы значения переменных $arComponentVariables
и $arDefaultVariableAliases404
$arComponentVariables = array( 'sort', 'dir' );
$arDefaultVariableAliases404 = array( 'section' => array( 'ELEMENT_COUNT' => 'count', ), );
и была запрошена страница
server.com/demo/category/id/28/?count=3&sort=date&dir=desc
то перемнная $arVariables
будет такой:
$arVariables = array ( 'SECTION_ID' => 28, 'ELEMENT_COUNT' => 3, 'sort' => 'date', 'dir' => 'desc' );
$arResult['VARIABLES'] = $arVariables; $arResult['FOLDER'] = $arParams['SEF_FOLDER']; $arResult['SECTION_URL'] = $arParams['SEF_FOLDER'].$arParams['SEF_URL_TEMPLATES']['section']; $arResult['ELEMENT_URL'] = $arParams['SEF_FOLDER'].$arParams['SEF_URL_TEMPLATES']['element']; $this->IncludeComponentTemplate($componentPage);
/test/index.php
, файл urlrewrite.php
в корне сервера будет перезаписан и в нем появится запись:
<?php $arUrlRewrite = array( 0 => array ( 'CONDITION' => '#^/test/#', 'RULE' => '', 'ID' => 'tokmakov:iblock', 'PATH' => '/test/index.php', 'SORT' => 100, ), );
Когда мы будем обращаться по адресам
/test/category/id/28/ /test/item/id/347/
которые физически не существуют, но соответствуют шаблону #^/test/#
— отвечать на обращения будет скрипт /test/index.php
, который содержит вызов комплексного компонента tokmakov:iblock
.
Вместо заключения
После разбора того, как работает комплексный компонент, все равно остались вопросы:
В режиме без поддержки ЧПУ
1. Зачем нужна переменная $arDefaultVariableAliases
, если она перезаписывается значениями из $arParams['VARIABLE_ALIASES']
? Если только исключить из файла настроек компонента VARIABLE_ALIASES
и использовать $arDefaultVariableAliases
, тем самым жестко прописав псевдонимы переменных в component.php
. Но тогда изменить это может только программист, а администратор сайта никак на это повлиять не сможет.
2. Зачем нужна переменная $arComponentVariables
, которая сообщает, какие переменные из $_REQUEST
должны попасть в $arVariables
. Зачем вообще нужно эти переменные сначала помещать в массив $arVariables
, чтобы потом передать их простым компонентам:
/* * Файл local/components/tokmakov/iblock/templates/.default/section.php */ $APPLICATION->IncludeComponent( 'tokmakov:iblock.section', '', array( /*...*/ 'ELEMENT_COUNT' => $arResult['VARIABLES']['count'], /*...*/ ) );
Ведь можно просто в local/components/tokmakov/iblock/templates/.default/section.php
написать
/* * Файл local/components/tokmakov/iblock/templates/.default/section.php */ $APPLICATION->IncludeComponent( 'tokmakov:iblock.section', '', array( /*...*/ 'ELEMENT_COUNT' => isset($_REQUEST['count']) ? $_REQUEST['count'] : $arParams['SECTION_ELEMENT_COUNT'], /*...*/ ) );
3. С псевдонимами переменных тоже не очень понятно. Зачем вообще было огород городить? Сейчас мы делаем так
/* * Файл local/components/tokmakov/iblock/.parameters.php */ $arComponentParameters = array( 'GROUPS' => array(/*...*/), 'PARAMETERS' => array( /*...*/ 'VARIABLE_ALIASES' => array( 'SECTION_ID' => array('NAME' => 'Идентификатор раздела'), 'SECTION_CODE' => array('NAME' => 'Символьный код раздела'), 'ELEMENT_ID' => array('NAME' => 'Идентификатор элемента'), 'ELEMENT_CODE' => array('NAME' => 'Символьный код элемента'), ), /*...*/ ) );
Если мы зададим псевдонимы SID
, SCODE
, EID
, ECODE
, после нажатия кнопки «Сохранить» в визуальном редакторе, Битрикс сформирует вызов компонента
<?php require($_SERVER["DOCUMENT_ROOT"]."/bitrix/header.php"); $APPLICATION->SetTitle("Статьи о домашних животных"); ?> <?php $APPLICATION->IncludeComponent( 'tokmakov:iblock', '', array( /*...*/ 'VARIABLE_ALIASES' => array( 'ELEMENT_CODE' => 'ECODE', 'ELEMENT_ID' => 'EID', 'SECTION_CODE' => 'SCODE', 'SECTION_ID' => 'SID' ), /*...*/ ) ); ?> <?php require($_SERVER["DOCUMENT_ROOT"]."/bitrix/footer.php"); ?>
Дальше мы восстанавливаем истинные переменные, чтобы передать их при вызове простых компонентов:
/* * Файл local/components/tokmakov/iblock/templates/.default/element.php */ $APPLICATION->IncludeComponent( 'tokmakov:iblock.element', '', array( /*...*/ 'ELEMENT_ID' => $arResult['VARIABLES']['ELEMENT_ID'], // идентификатор элемента инфоблока 'ELEMENT_CODE' => $arResult['VARIABLES']['ELEMENT_CODE'], // символьный код элемента инфоблока /*...*/ ), $component );
/* * Файл local/components/tokmakov/iblock/templates/.default/section.php */ $APPLICATION->IncludeComponent( 'tokmakov:iblock.section', '', array( /*...*/ 'SECTION_ID' => $arResult['VARIABLES']['SECTION_ID'], // идентификатор раздела инфоблока 'SECTION_CODE' => $arResult['VARIABLES']['SECTION_CODE'], // символьный код раздела инфоблока /*...*/ ), $component );
Но если мы удалим VARIABLE_ALIASES
из $arComponentParameters['PARAMETERS']
, а вместо этого добавим
/* * Файл local/components/tokmakov/iblock/.parameters.php */ $arComponentParameters = array( 'GROUPS' => array(/*...*/), 'PARAMETERS' => array( /*...*/ 'SECTION_ID' => array( // идентификатор раздела 'PARENT' => 'BASE', 'NAME' => 'Идентификатор раздела', 'TYPE' => 'STRING', 'DEFAULT' => '={$_REQUEST["SID"]}', ), 'SECTION_CODE' => array( // символьный код раздела 'PARENT' => 'BASE', 'NAME' => 'Символьный код раздела', 'TYPE' => 'STRING', 'DEFAULT' => '={$_REQUEST["SCODE"]}', ), 'ELEMENT_ID' => array( // идентификатор элемента 'PARENT' => 'BASE', 'NAME' => 'Идентификатор элемента', 'TYPE' => 'STRING', 'DEFAULT' => '={$_REQUEST["EID"]}', ), 'ELEMENT_CODE' => array( // символьный код элемента 'PARENT' => 'BASE', 'NAME' => 'Символьный код элемента', 'TYPE' => 'STRING', 'DEFAULT' => '={$_REQUEST["ECODE"]}', ), /*...*/ ) );
после нажатия кнопки «Сохранить» в визуальном редакторе, Битрикс сформирует такой вызов компонента
<?php require($_SERVER["DOCUMENT_ROOT"]."/bitrix/header.php"); $APPLICATION->SetTitle("Статьи о домашних животных"); ?> <?php $APPLICATION->IncludeComponent( 'tokmakov:iblock', '', array( /*...*/ 'ELEMENT_ID' => $_REQUEST['EID'], 'ELEMENT_CODE' => $_REQUEST['ECODE'], 'SECTION_CODE' => $_REQUEST['SCODE'], 'SECTION_ID' => $_REQUEST['SID'], /*...*/ ) ); ?> <?php require($_SERVER["DOCUMENT_ROOT"]."/bitrix/footer.php"); ?>
То тем самым получим соответствие
$arParams['SECTION_ID'] = $_REQUEST['SID'] $arParams['SECTION_CODE'] = $_REQUEST['SCODE'] $arParams['ELEMENT_ID'] = $_REQUEST['EID'] $arParams['ELEMENT_CODE'] = $_REQUEST['ECODE']
А при вызове простых компонетов напишем:
/* * Файл local/components/tokmakov/iblock/templates/.default/element.php */ $APPLICATION->IncludeComponent( 'tokmakov:iblock.element', '', array( /*...*/ 'ELEMENT_ID' => $arParams['ELEMENT_ID'], // идентификатор элемента инфоблока 'ELEMENT_CODE' => $arParams['ELEMENT_CODE'], // символьный код элемента инфоблока /*...*/ ), $component );
/* * Файл local/components/tokmakov/iblock/templates/.default/section.php */ $APPLICATION->IncludeComponent( 'tokmakov:iblock.section', '', array( /*...*/ 'SECTION_ID' => $arParams['SECTION_ID'], // идентификатор раздела инфоблока 'SECTION_CODE' => $arParams['SECTION_CODE'], // символьный код раздела инфоблока /*...*/ ), $component );
В режиме с поддержкой ЧПУ
1. Зачем нужна переменная $arDefaultVariableAliases404
? В режиме поддержки ЧПУ псевдонимы переменных через визуальный редактор вовсе передать нельзя, они не попадают в код вызова компонента. Определяя эту переменную, мы «зашиваем» в код компонента псевдонимы, которые администратор сайта не сможет переопределить. Только программист сможет дописать в код вызова компонента параметр VARIABLE_ALIASES
.
2. Зачем нужна переменная $arComponentVariables
— та же проблема, что и для режима без поддержки ЧПУ. Зачем наводить тень на плетень с передачей значений из $_REQUEST
в $arVariables
, а потом с передачей значений из $arVariables
в простой компонент? Сейчас мы делаем так
/* * Файл local/components/tokmakov/iblock/templates/.default/section.php */ $APPLICATION->IncludeComponent( 'tokmakov:iblock.section', '', array( /*...*/ 'ELEMENT_COUNT' => $arResult['VARIABLES']['count'], /*...*/ ) );
А можно просто в local/components/tokmakov/iblock/templates/.default/section.php
написать
/* * Файл local/components/tokmakov/iblock/templates/.default/section.php */ $APPLICATION->IncludeComponent( 'tokmakov:iblock.section', '', array( /*...*/ 'ELEMENT_COUNT' => isset($_REQUEST['count']) ? $_REQUEST['count'] : $arParams['SECTION_ELEMENT_COUNT'], /*...*/ ) );
3. С псевдонимами переменных еще более непонятно, чем в режиме без ЧПУ. Визуальный редактор при включении режима ЧПУ формирует вызов компонента вообще без параметра VARIABLE_ALIASES
:
<?php require($_SERVER["DOCUMENT_ROOT"]."/bitrix/header.php"); $APPLICATION->SetTitle("Статьи о домашних животных"); ?> <?php $APPLICATION->IncludeComponent( 'tokmakov:iblock', '', array( /*...*/ 'SEF_MODE' => 'Y', 'SEF_URL_TEMPLATES' => array( 'element'=>'item/id/#ELEMENT_ID#/', 'section'=>'category/id/#SECTION_ID#/', 'popular'=>'', ), /*...*/ ) ); ?> <?php require($_SERVER["DOCUMENT_ROOT"]."/bitrix/footer.php"); ?>
Потому что переменные мы получаем из шаблона пути SEF_URL_TEMPLATES
. «Восстановить» мы можем только переменные из QUERY_STRING
, если запрошена страница типа
http://server.com/demo/category/id/28/?count=3
Здесь из шаблона пути будет получена переменная SECTION_ID=28
. Хитрыми манипуляциями мы можем из $_REQUEST['count']
сделать $arVariables['ELEMENT_COUNT']
, чтобы в дальнейшем передать эту переменную простому компоненту:
/* * Файл local/components/tokmakov/iblock/templates/.default/section.php */ $APPLICATION->IncludeComponent( 'tokmakov:iblock.section', '', array( /*...*/ 'ELEMENT_COUNT' => $arResult['VARIABLES']['ELEMENT_COUNT'] ?: $arParams['SECTION_ELEMENT_COUNT'], /*...*/ ) );
А могли бы сделать просто, не связываясь с псевдонимами
/* * Файл local/components/tokmakov/iblock/templates/.default/section.php */ $APPLICATION->IncludeComponent( 'tokmakov:iblock.section', '', array( /*...*/ 'ELEMENT_COUNT' => isset($_REQUEST['count']) ? $_REQUEST['count'] : $arParams['SECTION_ELEMENT_COUNT'], /*...*/ ) );
4. Зачем нужна переменная $arDefaultUrlTemplates404
, если она перезаписывается значениями из $arParams['SEF_URL_TEMPLATES']
? Если только в настройках компонента вовсе убрать возможность влиять на шаблоны URL, а прописывать их в component.php
. Но тогда изменить это сможет только программист, а администратор сайта никак на это повлиять не сможет.
Дополнительно
- Битрикс. Создание комплексного компонента. Часть 3 из 4
- Битрикс. Создание комплексного компонента. Часть 2 из 4
- Битрикс. Создание комплексного компонента. Часть 1 из 4
- Битрикс. Работа с инфоблоками в старом ядре
- Битрикс. Работа с инфоблоками в новом ядре
- Битрикс. Работа с шаблонами SEO
- Битрикс. Создание простого компонента. Часть 2 из 2
Поиск: CMS • Web-разработка • Битрикс • Инфоблок • Компонент • Раздел инфоблока • Шаблон компонента • Элемент инфоблока