Создание простого компонента
Готовый код можно скачать в моем репозитории на GitFlic. Давайте создадим простой компонент который будет выводить слайдер на сайт.
В Битрикс существует понятие пространство имен. Все стандартные компоненты Битрикс находятся в пространстве имен
Bitrix
в папочке /bitrix/components/bitrix/
. Свои компоненты нужно располагать в своем пространстве имен, т.е. в папочке /bitrix/components/my_components/
или ещё лучше в папке /local/components/my_components/
. При этом my_components
- это наше пространство имен. Компонент будет называться glavnyj.slajder
. Минимальная структура файлов компонента должна быть следующая:
- Файл
.description.php
- Файл
.parameters.php
- Файл
component.php
- Папка
templates
.description.php
В файле .description.php
задаем имя, описание и расположение компонента в визуальном редакторе, если ключ PATH
не задан, то компонент не будет присутствовать в визуальном редакторе:
glavnyj.slajder/.description.php<?
if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die();
$arComponentDescription = array(
// название компонента
'NAME' => 'Главный слайдер на странице',
// описание компонента
'DESCRIPTION' => 'Выводит главный слайдер в шапке страницы',
// путь к иконке компонента относительно папки компонента
'ICON' => '/images/eaddlist.gif',
// показывать кнопку очистки кеша
'CACHE_PATH' => 'Y',
// порядок сортировки в визуальном редакторе
'SORT' => 30,
// признак комплексного компонента
'COMPLEX' => 'N',
// расположение компонента в визуальном редакторе
'PATH' => array(
// идентификатор верхнего уровеня в редакторе
'ID' => 'slajder',
// название верхнего уровня в редакторе
'NAME' => 'Слайдеры',
// в элементе может быть задана подчиненная ветка дерева с той же структурой, что и родительская ветка
'CHILD' => '',
)
);
.parameters.php
В файле .parameters.php
содержится описание входных параметров компонента. Это описание применяется для работы с компонентом из среды БУС (например, в визуальном редакторе), а так же при работе в режиме редактирования сайта. При работе самого компонента (при обращении к странице, на которой расположен компонент) описание не используется и файл .parameters.php
не подключается:
glavnyj.slajder/.parameters.php<?
if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true) die();
// проверяем установку модуля «Информационные блоки»
if (!CModule::IncludeModule('iblock')) {
return;
}
// получаем массив всех типов инфоблоков для возможности выбора
$arIBlockType = CIBlockParameters::GetIBlockTypes();
// пустой массив для вывода
$arInfoBlocks = array();
// выбираем активные инфоблоки
$arFilterInfoBlocks = array('ACTIVE' => 'Y');
// сортируем по озрастанию поля сортировка
$arOrderInfoBlocks = array('SORT' => 'ASC');
// если уже выбран тип инфоблока, выбираем инфоблоки только этого типа
if (!empty($arCurrentValues['IBLOCK_TYPE'])) {
$arFilterInfoBlocks['TYPE'] = $arCurrentValues['IBLOCK_TYPE'];
}
// метод выборки информационных блоков
$rsIBlock = CIBlock::GetList($arOrderInfoBlocks, $arFilterInfoBlocks);
// перебираем и выводим в адмику доступные информационные блоки
while ($obIBlock = $rsIBlock->Fetch()) {
$arInfoBlocks[$obIBlock['ID']] = '[' . $obIBlock['ID'] . '] ' . $obIBlock['NAME'];
}
// настройки компонента, формируем массив $arParams
$arComponentParameters = array(
// название кастомной группы не обязательный параметр
"GROUPS" => array(
"TEST" => array(
"NAME" => 'Тест'
),
),
// основной массив с параметрами
'PARAMETERS' => array(
// выбор типа инфоблока
'IBLOCK_TYPE' => array( // ключ массива $arParams в component.php
'PARENT' => 'TEST', // название группы
'NAME' => 'Выберите тип инфоблока', // название параметра
'TYPE' => 'LIST', // тип элемента управления, в котором будет устанавливаться параметр
'VALUES' => $arIBlockType, // входные значения
'REFRESH' => 'Y', // перегружать настройки или нет после выбора (N/Y)
'DEFAULT' => 'news', // значение по умолчанию
'MULTIPLE' => 'N', // одиночное/множественное значение (N/Y)
),
// выбор самого инфоблока
'IBLOCK_ID' => array(
'PARENT' => 'BASE',
'NAME' => 'Выберите родительский инфоблок',
'TYPE' => 'LIST',
'VALUES' => $arInfoBlocks,
'REFRESH' => 'Y',
"DEFAULT" => '',
"ADDITIONAL_VALUES" => "Y",
),
// настройки кэширования
'CACHE_TIME' => array(
'DEFAULT' => 3600
),
),
);
Перечень стандартных элементов для массива 'PARAMETERS'
:
Элемент
|
Значение
|
---|---|
PARENT
|
Код группы, если нет - ставится ADDITIONAL_SETTINGS |
NAME
|
Название параметра на текущем языке |
TYPE
|
Тип элемента управления, в котором будет устанавливаться параметр. Для типа элемента управления TYPE есть значения:
MULTIPLE и ADDITIONAL_VALUES :
|
REFRESH
|
Перегружать настройки или нет после выбора (N/Y). Позволяет после выбора значения перегрузить всю форму с параметрами. Делается это, например, для выбора инфоблока конкретного типа. То есть имеем два параметра - тип инфоблока и код инфоблока. Исходное положение - в первом список всех типов инфоблоков, во втором - список всех инфоблоков данного сайта, а после выбора нужного типа инфоблока параметры компонента перегружаются и мы видим только инфоблоки нужного типа |
MULTIPLE
|
Одиночное/множественное значение (N/Y) |
VALUES
|
Массив значений для списка (TYPE = LIST) |
ADDITIONAL_VALUES
|
Показывать поле для значений, вводимых вручную (Y/N) |
SIZE
|
Число строк для списка (если нужен не выпадающий список) |
DEFAULT
|
Значение по умолчанию |
COLS
|
Ширина поля в символах |
Перечень стандартных групп для 'PARAMETERS'->'PARENT'
:
Код
|
Сортировка
|
Название
|
Описание
|
---|---|---|---|
BASE
|
100 | Основные параметры | Базовые параметры для работы компонента |
DATA_SOURCE
|
200 | Источник данных | Параметры, указывающие, откуда выбирать данные для компонента (к примеру, для компонент модуля Инфоблоки это тип и ID инфоблока) |
VISUAL
|
300 | Настройки внешнего вида | Сюда предполагается размещать параметры, отвечающие за внешний вид |
USER_CONSENT
|
350 | Согласие пользователя | Настрйока параметров на получение согласия пользователя, согласно законодательству РФ |
URL_TEMPLATES
|
400 | Шаблоны ссылок | Служебная |
SEF_MODE
|
500 | Управление адресами страниц | Группа для всех параметров, связанных с использованием ЧПУ |
AJAX_SETTINGS
|
550 | Управление режимом AJAX | Все, что касается использования AJAX |
CACHE_SETTINGS
|
600 | Настройки кеширования | Появляется при указании параметра CACHE_TIME |
ADDITIONAL_SETTINGS
|
700 | Дополнительные настройки | Эта группа появляется, например, при указании параметра SET_TITLE |
Особые параметры
Существуют особые параметры, которые стандартизованы и которые нет необходимости описывать полностью. Достаточно указать, что они есть. Первый из указанных параметров указывает, следует ли компоненту установить заголовок страницы, а второй - все настройки, связанные с кешированием.
"SET_TITLE" => array(),
"CACHE_TIME" => array(),
Только комплексные компоненты могут работать в режиме ЧПУ или переопределять переменные, которые приходят из
HTTP
запроса. В этом случае необходимо среди параметров указать ещё два особых параметра:
VARIABLE_ALIASES
массив, описывающий переменные, которые компонент может получать из HTTP
запроса. Каждый элемент массива имеет вид:
"внутреннее название переменной" => array(
"NAME" => "название переменной на текущем языке",
)
SEF_MODE
массив, описывающий шаблоны путей в режиме ЧПУ. Каждый элемент массива имеет вид:
"код шаблона пути" => array(
"NAME" => "название шаблона пути на текущем языке",
"DEFAULT" => "шаблон пути по-умолчанию",
"VARIABLES" => "массив внутренних названий переменных, которые могут использоваться в шаблоне"
)
component.php
В файле component.php
размещаем код, получающий из базы данных элемент инфоблока по идентификатору:
glavnyj.slajder/component.php<?
if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true) die();
// время кеширования
if (!isset($arParams['CACHE_TIME'])) {
$arParams['CACHE_TIME'] = 3600;
} else {
$arParams['CACHE_TIME'] = intval($arParams['CACHE_TIME']);
}
// если нет валидного кеша — получаем данные из БД
if ($this->StartResultCache()) {
// проверяем, установлен ли модуль «Информационные блоки»
if (!CModule::IncludeModule('iblock')) {
return;
}
// получаем данные из базы
$res1 = CIBlockElement::GetList(
array("SORT" => "ASC"),
array("IBLOCK_ID" => $arParams["IBLOCK_ID"], 'ACTIVE' => 'Y'),
false,
array(),
array("ID", "IBLOCK_ID", "NAME", "PROPERTY_ID_2_ZAGOLOVOK", "PROPERTY_ID_2_TEXT", "PROPERTY_ID_2_ZAGOLOVOKHOVER", "PROPERTY_ID_2_TEXTHOVER", "PROPERTY_ID_2_KARTINKA", "PREVIEW_PICTURE", "PROPERTY_ID_2_HREF"),
);
// формируем массив arResult
while ($arr = $res1->GetNext()) {
$arr["PROPERTY_ID_2_KARTINKA_VALUE"] = CFile::GetFileArray($arr["PROPERTY_ID_2_KARTINKA_VALUE"]);
$arr["PREVIEW_PICTURE"] = CFile::GetFileArray($arr["PREVIEW_PICTURE"]);
$arResult[] = $arr;
};
// кэш не затронет весь код ниже, он будут выполняться на каждом хите, но здесь работаем уже с другим $arResult — будут доступны только те ключи массива, которые перечислены в вызове SetResultCacheKeys()
if (isset($arResult)) {
// ключи $arResult, перечисленные при вызове этого метода, будут доступны в component_epilog.php и ниже по коду. Обратите внимание, там уже будет другой $arResult
$this->SetResultCacheKeys(
array()
);
// подключаем шаблон и сохраняем кеш
$this->IncludeComponentTemplate();
} else { // если выяснилось что кешировать данные не требуется, прерываем кеширование и выдаем сообщение, что такой страницы нет
$this->AbortResultCache();
\Bitrix\Iblock\Component\Tools::process404(
'Страница не найдена',
true,
true
);
}
};
Пользовательские свойства инфоблоков можно получать двумя способами:
- Перечислением всех свойств
- Воспользоваться методом
GetProperties()
Подробнее о методе GetProperties()
можно почитать в статье Пользовательские свойства элемента инфоблока
template.php
Шаблон компонента, отвечает за показ элемента инфоблока:
glavnyj.slajder/template/.default/template.php<? if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die(); ?>
<section>
<div class="container product_slider">
<div class="swiper mySwiper4">
<div class="swiper-wrapper">
<? foreach ($arResult as $arElement) : ?>
<?
// ссылки для экшенов и название кнопки
$arButtons = CIBlock::GetPanelButtons(
// идентификатор инфоблока, которому принадлежит элемент
$arElement["IBLOCK_ID"],
// идентификатор текущего элемента информационного блока
$arElement["ID"],
// идентификатор раздела инфоблока (при наличии)
0,
// массив, содержащий локализацию названий
array("SECTION_BUTTONS" => false, "SESSID" => false)
);
// экшен изменения элемента
$this->AddEditAction(
// идентификатор текущего элемента информационного блока
$arElement["ID"],
// ссылка из $arButtons на изменение эллемента
$arButtons["edit"]["edit_element"]["ACTION_URL"],
// название кнопки
$arButtons["edit"]["edit_element"]["TEXT"]
);
// экшен добавления элемента
$this->AddEditAction(
// идентификатор текущего элемента информационного блока
$arElement["ID"],
// ссылка из $arButtons на изменение эллемента
$arButtons["edit"]["add_element"]["ACTION_URL"],
// название кнопки
$arButtons["edit"]["add_element"]["TEXT"]
);
// экшен удаления элемента
$this->AddDeleteAction(
// идентификатор текущего элемента информационного блока
$arElement["ID"],
// ссылка из $arButtons на изменение эллемента
$arButtons["edit"]["delete_element"]["ACTION_URL"],
// название кнопки
$arButtons["edit"]["delete_element"]["TEXT"],
array("CONFIRM" => "Удалить?")
); ?>
<?
// проверка на администратора для вывода экшенов
if ($USER->IsAdmin() && $APPLICATION->GetShowIncludeAreas()) {
echo '<div class="swiper-slide" id="' . $this->GetEditAreaId($arElement["ID"]) . '">';
} else {
echo '<div class="swiper-slide">';
}
?>
<div class="product">
<div class="item">
<div class="row">
<div class="col-8 title"><?= $arElement["PROPERTY_ID_2_ZAGOLOVOK_VALUE"] ?></div>
<div class="col-4 image"><img src="<?= "/local/templates/hmarketing/img/svg/icons/" . preg_replace('#[a-z]{3,4}$#', 'svg', $arElement["PREVIEW_PICTURE"]["ORIGINAL_NAME"], 1) ?>" alt="<?= $arElement["PREVIEW_PICTURE"]["DESCRIPTION"] ?>" width="40" height="40"></div>
<div class="col-12 tekst"><?= $arElement["PROPERTY_ID_2_TEXT_VALUE"] ?></div>
<div class="col-12 button">Узнать больше<span class="icon-arrow-right"></div>
</div>
</div>
<div class="hover swiper-lazy" data-background="<?= $arElement["PROPERTY_ID_2_KARTINKA_VALUE"]["SRC"] ?>">
<div class="row">
<div class="col-12 title"><?= $arElement["PROPERTY_ID_2_ZAGOLOVOKHOVER_VALUE"] ?></div>
<div class="col-12 tekst"><?= $arElement["PROPERTY_ID_2_TEXTHOVER_VALUE"] ?></div>
<div class="col-12 button"><a href="<?= $arElement["PROPERTY_ID_2_HREF_VALUE"] ?>">Жми подробнее... <span class="icon-arrow-right"></span></a></div>
</div>
</div>
</div>
<? echo '</div>'; ?>
<? endforeach ?>
</div>
<div class="slider-nav">
<div class="swiper-prev"></div>
<div class="swiper-indicators"></div>
<div class="swiper-next"></div>
</div>
</div>
</section>
Логика работы компонента
Компонент - логически завершенный код - состоит из ряда папок и файлов. Часть из них обязательна, без которых он работать не будет, часть может отсутствовать.
Компонент получает входящие параметры из массива $arParams
, затем обрабатывает полученную информацию и формирует итог работы в массив $arResult
. Если у компонента имеется визуальное представление, то подключается шаблон, и в него передается данные из массива $arParams
и $arResult
, на основании которых строится вывод всей информации на странице сайта.