10 декабря 2017
Но внедрять PHP код и API Битрикс непосредственно в шаблон не очень правильное решение, не bitrix-way, так сказать. Поэтому для вывода слайдера мы создадим собственный компонент. Ну и конечно при этом научимся создавать свои собственные компоненты Битрикс.
В своем примере я буду располагать компоненты в пространстве имен startshop по пути /local/components/startshop/. Компонент так и назову slider.
Минимальная структура файлов компонента должна быть следующая:
В этом фале задается наименование и описание компонента. А так же иконка для отображения в палитре компонентов и параметр PATH указывает на то, в какой папочке будет находится компонент в палитре компонентов.
.parameters.php
В файле параметров все намного сложнее. Но если вы уже немного владеете API Битрикс, то можно понять, что верхний код на API Битрикс получает три массива:
Вот такие параметры будут доступны в настройках нашего компонента из публичной части сайта.
component.php
Код компонента получился очень короткий в отличие от стандартного кода вывода списка новостей. Тут нет ничего лишнего. Вначале мы объявили пространство имен для загрузчика Loader, далее с его помощью подгрузили модуль инфоблоков iblock. И с помощью самой распространенной конструкции API Bitrix CIBlockElement::GetList() выполнили запрос к базе данных отобрав записи инфоблока Товары, в котором свойство Слайдер установлено в занчение "Да". Далее результатом выборки заполнили предопределенный массив $arResult и последней строкой подключили файл шаблона.
templates/.default/template.php
Шаблон даже получился более громоздкий, чем компонент. Но если посмотрите тут все просто. Код верстки слайдера взять целиком из CSS-фреймворка Foundation. Далее я уже приводил принцип работы с массивом $arResult в уроке когда мы выводили каталог товаров. Делаем выполняем цикл по массиву и выводим нужные нам значения. Тут пришлось правда два цикла сделать - не очень оптимально, но это не обращение к базе данных и цикл по массиву из 3-5 записей не нагрузит ваш сайт. По этому усложнять код и избегать второго цикла я счел не нужным.
Строкой $file = CFile::ResizeImageGet($item["PREVIEW_PICTURE"], array('width' => 1100,'height' => 500), BX_RESIZE_IMAGE_EXACT, true); я снова подгоняю картинки под требуемый размер. Подробнее все в том же уроке про вывод каталога.
Вот что в итоге получилось.
Тут конечно надо заметить, что не очень красиво получилось. По хорошему нужно подобрать пропорциональные картинки и разместить их в отдельном инфоблоке. Вы попробуйте так и сделать, код компонента при этом обсалютно не изменится, даже упростится, не потребуется условие отбора по свойству Слайдер. Вобщем пример при этом не страдает, по этому переделывать я не стану, а лучше напишу побыстрее следующий урок.
И как всегда выкладываю исходный код урока:
компонент slider
шаблон этого урока
От автора:
А на этом пока все. Собственно, что касается вывода информации почти все готово, остаются мелочи. Т.е. витрина у нас уже готова и работает. Дальше нужно делать функционал магазина, а это значит карнизу и заказы. Подписывайтесь и ждите новых статей, дальше будет интереснее.
Урок 9. Создание собственного компонента слайдера для интернет-магазина на Битрикс на CMS-Foundation
Приветствую моих читателей! Мы продолжаем строить наш собственный интернет-магазин на Битрикс редакции Старт. В прошлых уроках мы уже реализовали адаптивный каталог товаров и сделали карточку товара. Теперь пришло время немного подкрасить наш магазин и внести такую модную штуку, как слайдер. Если бы мы не пользовались никаким CSS-фреймворками, то нам потребовалось бы изучать Java Script и JQuery. Или по крайней мере искать в интернете готовые скрипты и как-то их прикручивать к сайту. Но как вы помните наш интернет магазин строится полностью на CSS-фреймворке Foundation, а в нём уже есть готовый класс для слайдера Orbit.Но внедрять PHP код и API Битрикс непосредственно в шаблон не очень правильное решение, не bitrix-way, так сказать. Поэтому для вывода слайдера мы создадим собственный компонент. Ну и конечно при этом научимся создавать свои собственные компоненты Битрикс.
План создания компонента Битрикс
Логику работы мы заложим следующую. Слайдер будет строится на том же инфоблоке Товары, что и каталог. Но попадать в слайдер будут только те товары, у которых задано свойство Слайдер (SLIDER). Входными параметрами для нашего компонента будет Тип инфоблока, Инфоблок и свойство указывающее, что необходимо выводить слайдер.
Если у вас нет свойства Слайдер в инфоблоке добавьте его.
Тип у свойство должен быть список.
Инфоблок настроили, теперь можно приступить к созданию собственного компонента Битрикс. Что может быть интереснее написания собственных компонент?...
Создание компонента Битрикс
В Битрикс существует понятие пространство имен. Все стандартные компоненты Битрикс находятся в пространстве имен Bitrix в папочке /bitrix/components/bitrix/. Свои компоненты нужно располагать в своем пространстве имен, т.е. в папочке /bitrix/components/my/ или ещё лучше в папке /local/components/my/. my - это наше пространство имен.В своем примере я буду располагать компоненты в пространстве имен startshop по пути /local/components/startshop/. Компонент так и назову slider.
Минимальная структура файлов компонента должна быть следующая:
-
component.php - основной фал компонента, реализация логики работы компонента на API Bitrix.
.description.php - файл описания компонента.
- .parameters.php - файл параметров компонента.
-
templates/.default/template.php - файл шаблона по умолчанию для компонента.
Содержание этих файлов у нас будет следующим:
.description.php
<?
if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true) die();
$arComponentDescription = array(
"NAME" => "Слайдер",
"DESCRIPTION" => "Слайдер на фреймворке CSS Foundation",
"ICON" => "/images/icon.gif",
"SORT" => 100,
"CACHE_PATH" => "Y",
"PATH" => array(
"ID" => "startshop",
"NAME" => 'Компоненты StartShop'
),
);
?>
if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true) die();
$arComponentDescription = array(
"NAME" => "Слайдер",
"DESCRIPTION" => "Слайдер на фреймворке CSS Foundation",
"ICON" => "/images/icon.gif",
"SORT" => 100,
"CACHE_PATH" => "Y",
"PATH" => array(
"ID" => "startshop",
"NAME" => 'Компоненты StartShop'
),
);
?>
В этом фале задается наименование и описание компонента. А так же иконка для отображения в палитре компонентов и параметр PATH указывает на то, в какой папочке будет находится компонент в палитре компонентов.
<?
if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true) die();
if(!CModule::IncludeModule("iblock"))
return;
$arTypesEx = CIBlockParameters::GetIBlockTypes(array("-"=>" "));
$arIBlocks=array();
$db_iblock = CIBlock::GetList(array("SORT"=>"ASC"), array("TYPE" => ($arCurrentValues["IBLOCK_TYPE"]!="-"?$arCurrentValues["IBLOCK_TYPE"]:"")));
while($arRes = $db_iblock->Fetch())
$arIBlocks[$arRes["ID"]] = "[".$arRes["ID"]."] ".$arRes["NAME"];
$arProperty_LNS = array();
$rsProp = CIBlockProperty::GetList(array("sort"=>"asc", "name"=>"asc"), array("ACTIVE"=>"Y", "IBLOCK_ID"=>($arCurrentValues["IBLOCK_ID"])));
while ($arr=$rsProp->Fetch())
{
$arProperty[$arr["CODE"]] = "[".$arr["CODE"]."] ".$arr["NAME"];
if (in_array($arr["PROPERTY_TYPE"], array("L", "N", "S")))
{
$arProperty_LNS[$arr["CODE"]] = "[".$arr["CODE"]."] ".$arr["NAME"];
}
}
$arComponentParameters = array(
"PARAMETERS" => array(
"IBLOCK_TYPE" => array(
"PARENT" => "BASE",
"NAME" => "Тип инфоблока",
"TYPE" => "LIST",
"VALUES" => $arTypesEx,
"DEFAULT" => "news",
"REFRESH" => "Y",
),
"IBLOCK_ID" => array(
"PARENT" => "BASE",
"NAME" => "Инфобок",
"TYPE" => "LIST",
"VALUES" => $arIBlocks,
"DEFAULT" => '={$_REQUEST["ID"]}',
"ADDITIONAL_VALUES" => "Y",
"REFRESH" => "Y",
),
"PROPERTY_CODE" => array(
"PARENT" => "DATA_SOURCE",
"NAME" => "Укажите свойство по которому будет фильтроваться товары для слайдера",
"TYPE" => "LIST",
"MULTIPLE" => "N",
"VALUES" => $arProperty_LNS,
"ADDITIONAL_VALUES" => "Y",
),
),
);
if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true) die();
if(!CModule::IncludeModule("iblock"))
return;
$arTypesEx = CIBlockParameters::GetIBlockTypes(array("-"=>" "));
$arIBlocks=array();
$db_iblock = CIBlock::GetList(array("SORT"=>"ASC"), array("TYPE" => ($arCurrentValues["IBLOCK_TYPE"]!="-"?$arCurrentValues["IBLOCK_TYPE"]:"")));
while($arRes = $db_iblock->Fetch())
$arIBlocks[$arRes["ID"]] = "[".$arRes["ID"]."] ".$arRes["NAME"];
$arProperty_LNS = array();
$rsProp = CIBlockProperty::GetList(array("sort"=>"asc", "name"=>"asc"), array("ACTIVE"=>"Y", "IBLOCK_ID"=>($arCurrentValues["IBLOCK_ID"])));
while ($arr=$rsProp->Fetch())
{
$arProperty[$arr["CODE"]] = "[".$arr["CODE"]."] ".$arr["NAME"];
if (in_array($arr["PROPERTY_TYPE"], array("L", "N", "S")))
{
$arProperty_LNS[$arr["CODE"]] = "[".$arr["CODE"]."] ".$arr["NAME"];
}
}
$arComponentParameters = array(
"PARAMETERS" => array(
"IBLOCK_TYPE" => array(
"PARENT" => "BASE",
"NAME" => "Тип инфоблока",
"TYPE" => "LIST",
"VALUES" => $arTypesEx,
"DEFAULT" => "news",
"REFRESH" => "Y",
),
"IBLOCK_ID" => array(
"PARENT" => "BASE",
"NAME" => "Инфобок",
"TYPE" => "LIST",
"VALUES" => $arIBlocks,
"DEFAULT" => '={$_REQUEST["ID"]}',
"ADDITIONAL_VALUES" => "Y",
"REFRESH" => "Y",
),
"PROPERTY_CODE" => array(
"PARENT" => "DATA_SOURCE",
"NAME" => "Укажите свойство по которому будет фильтроваться товары для слайдера",
"TYPE" => "LIST",
"MULTIPLE" => "N",
"VALUES" => $arProperty_LNS,
"ADDITIONAL_VALUES" => "Y",
),
),
);
В файле параметров все намного сложнее. Но если вы уже немного владеете API Битрикс, то можно понять, что верхний код на API Битрикс получает три массива:
- $arTypesEx - массив с типами доступных инфоблоков.
- $arIBlocks - массив со списком инфоблоков отфильтрованному по данному типу.
- $arProperty_LNS - массив всех свойств выбранного инфоблока.
Вот такие параметры будут доступны в настройках нашего компонента из публичной части сайта.
component.php
<?
if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();
use Bitrix\Main\Loader;
if(!Loader::includeModule("iblock"))
{
return;
}
$arSelect = Array("ID", "NAME", "PREVIEW_PICTURE", "DETAIL_PAGE_URL", "PROPERTY_".$arParams["PROPERTY_CODE"]);
$arFilter = Array("IBLOCK_ID" => IntVal($arParams["IBLOCK_ID"]), "ACTIVE"=>"Y", "PROPERTY_".$arParams["PROPERTY_CODE"]."_VALUE" => 'Да');
$res = CIBlockElement::GetList(Array(), $arFilter, false, false, $arSelect);
while($arFields = $res->GetNext())
{
$arResult[] = $arFields;
}
$this->includeComponentTemplate();
?>
if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();
use Bitrix\Main\Loader;
if(!Loader::includeModule("iblock"))
{
return;
}
$arSelect = Array("ID", "NAME", "PREVIEW_PICTURE", "DETAIL_PAGE_URL", "PROPERTY_".$arParams["PROPERTY_CODE"]);
$arFilter = Array("IBLOCK_ID" => IntVal($arParams["IBLOCK_ID"]), "ACTIVE"=>"Y", "PROPERTY_".$arParams["PROPERTY_CODE"]."_VALUE" => 'Да');
$res = CIBlockElement::GetList(Array(), $arFilter, false, false, $arSelect);
while($arFields = $res->GetNext())
{
$arResult[] = $arFields;
}
$this->includeComponentTemplate();
?>
Код компонента получился очень короткий в отличие от стандартного кода вывода списка новостей. Тут нет ничего лишнего. Вначале мы объявили пространство имен для загрузчика Loader, далее с его помощью подгрузили модуль инфоблоков iblock. И с помощью самой распространенной конструкции API Bitrix CIBlockElement::GetList() выполнили запрос к базе данных отобрав записи инфоблока Товары, в котором свойство Слайдер установлено в занчение "Да". Далее результатом выборки заполнили предопределенный массив $arResult и последней строкой подключили файл шаблона.
templates/.default/template.php
<?
if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();
?>
<div class="orbit" role="region" aria-label="Favorite Space Pictures" data-orbit>
<div class="orbit-wrapper">
<div class="orbit-controls">
<button class="orbit-previous"><span class="show-for-sr">Предыдущий</span>◀︎</button>
<button class="orbit-next"><span class="show-for-sr">Следующий</span>▶︎</button>
</div>
<ul class="orbit-container">
<?foreach ($arResult as $item): ?>
<?
$file = CFile::ResizeImageGet($item["PREVIEW_PICTURE"], array('width' => 1100,'height' => 500), BX_RESIZE_IMAGE_EXACT, true);
?>
<li class="orbit-slide">
<figure class="orbit-figure">
<img class="orbit-image" src="<?=$file['src']?>" alt="Space">
<figcaption class="orbit-caption"><?=$item['NAME']?></figcaption>
</figure>
</li>
<?endforeach;?>
</ul>
</div>
<nav class="orbit-bullets">
<?foreach ($arResult as $item=>$key): ?>
<button data-slide="<?=$key?>"><span class="show-for-sr"><?=$item['NAME']?></span></button>
<?endforeach;?>
</nav>
</div>
if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();
?>
<div class="orbit" role="region" aria-label="Favorite Space Pictures" data-orbit>
<div class="orbit-wrapper">
<div class="orbit-controls">
<button class="orbit-previous"><span class="show-for-sr">Предыдущий</span>◀︎</button>
<button class="orbit-next"><span class="show-for-sr">Следующий</span>▶︎</button>
</div>
<ul class="orbit-container">
<?foreach ($arResult as $item): ?>
<?
$file = CFile::ResizeImageGet($item["PREVIEW_PICTURE"], array('width' => 1100,'height' => 500), BX_RESIZE_IMAGE_EXACT, true);
?>
<li class="orbit-slide">
<figure class="orbit-figure">
<img class="orbit-image" src="<?=$file['src']?>" alt="Space">
<figcaption class="orbit-caption"><?=$item['NAME']?></figcaption>
</figure>
</li>
<?endforeach;?>
</ul>
</div>
<nav class="orbit-bullets">
<?foreach ($arResult as $item=>$key): ?>
<button data-slide="<?=$key?>"><span class="show-for-sr"><?=$item['NAME']?></span></button>
<?endforeach;?>
</nav>
</div>
Шаблон даже получился более громоздкий, чем компонент. Но если посмотрите тут все просто. Код верстки слайдера взять целиком из CSS-фреймворка Foundation. Далее я уже приводил принцип работы с массивом $arResult в уроке когда мы выводили каталог товаров. Делаем выполняем цикл по массиву и выводим нужные нам значения. Тут пришлось правда два цикла сделать - не очень оптимально, но это не обращение к базе данных и цикл по массиву из 3-5 записей не нагрузит ваш сайт. По этому усложнять код и избегать второго цикла я счел не нужным.
Строкой $file = CFile::ResizeImageGet($item["PREVIEW_PICTURE"], array('width' => 1100,'height' => 500), BX_RESIZE_IMAGE_EXACT, true); я снова подгоняю картинки под требуемый размер. Подробнее все в том же уроке про вывод каталога.
Вот что в итоге получилось.
Тут конечно надо заметить, что не очень красиво получилось. По хорошему нужно подобрать пропорциональные картинки и разместить их в отдельном инфоблоке. Вы попробуйте так и сделать, код компонента при этом обсалютно не изменится, даже упростится, не потребуется условие отбора по свойству Слайдер. Вобщем пример при этом не страдает, по этому переделывать я не стану, а лучше напишу побыстрее следующий урок.
И как всегда выкладываю исходный код урока:
компонент slider
шаблон этого урока
От автора:
А на этом пока все. Собственно, что касается вывода информации почти все готово, остаются мелочи. Т.е. витрина у нас уже готова и работает. Дальше нужно делать функционал магазина, а это значит карнизу и заказы. Подписывайтесь и ждите новых статей, дальше будет интереснее.
Комментарии
Почему же не работать с визуальной частью сайта (в частности с картинками) средствами CSS?? Зачем городить php для картинок и в предыдущих уроках сетку под разные экраны?? Ведь для этого верстка на CSS Foundation! Эх)
А как средствами CSS можно смасштабировать картинку, которая изначально не подходящего размера и не потерять пропорции?
Например так img { max-width:100%; height:auto; }
Как вариант да, но если изображении сильно не пропорциональное оно уменьшится. А в случае обработки через CFile::ResizeImageGet() обрезается. Вобщем чтобы иметь качественный каталог, нужно изначально хорошие пропорциональные изображения. Я на это время не тратил.