Меню

1С УПРАВЛЕНИЕ ТОРГОВЛЕЙ И ИНТЕРНЕТ-МАГАЗИН БИТРИКС

17 Ноября 2017

Урок 7. Параметры компонента битрикс и result_modifier.php

Приветствую. В предыдущем уроке мы вывели товары на страницу каталога. Собственно почти готов интернет-магазин, по крайней мере витрина. Но если вы посмотрите, то каталог выводится не очень хорошо, из за того, что разный размер изображений и разная длинна наименования (в одну и две строки) карточки товаров "скачут".

Каталог Битрикс

Вот так сейчас должен выглядеть наш каталог. Видно 2 проблемы:
  1. Разная высота и ширина карточек
  2. Наименование выводится в две строки и сдвигает в низ цену и кнопку Купить.
Вот сейчас мы их решим.

Изменение результата работы компонента через result_modifier.php

Первая проблема это то, что изображения предварительного просмотра добавлены в инфоблок разных размеров. Ситуация распространенная, т.к. подгонять все изображение под один размер до миллиметра это не реально. Хотя конечно изображения должны быть примерно одинаковых размеров.
Что нам нужно сделать? Просто версткой, указанием размеров блока изображения проблему не решить, т.к. картинки растянутся не пропорционально. Нужно делать полноценный resize с сохранением пропорций. И в этой задаче нам тоже поможет богатое  API Битрикса, в нем есть все функции для этого, а точнее нам понадобится всего одна CFile::ResizeImageGet.
Чтобы изменить размер изображений в инфоблоке Битрикс нужно выполнить следующий код.

Код:
foreach($arResult["ITEMS"] as $cell=>$arElement)
{
  if($arElement["PREVIEW_PICTURE"]["ID"])
  {
    $file = CFile::ResizeImageGet($arElement["PREVIEW_PICTURE"]["ID"],array('width' => 200,'height' => 200), BX_RESIZE_IMAGE_EXACT, true);
    $arResult["ITEMS"][$cell]["PREVIEW_PICTURE"]['WIDTH'] = $file['width'];
    $arResult["ITEMS"][$cell]["PREVIEW_PICTURE"]['HEIGHT'] = $file['height'];
    $arResult["ITEMS"][$cell]["PREVIEW_PICTURE"]['SRC'] = $file['src'];
  }
}
Мы снова в цикле обходим элементы массива $arResult и функцией CFile::ResizeImageGet() изменяем размер изображения.
Подробнее о функции можно посмотреть в документации Битрикс. После преобразования мы устанавливаем параметры ширины и высоты изображения 200 пикселов. Но главное мы в качестве источника изображения указываем наш преобразованный файл.
$arResult["ITEMS"][$cell]["PREVIEW_PICTURE"]['SRC'] = $file['src'];

Данный код можно разместить и в самом шаблоне компонента news.list или в специальном файле result_modifier.php, который должен находится в то же папке где и файл шаблона компонента. На нем я остановлюсь поподробней, т.к. это интересная технология модификации результата работы компонента без изменения кода компонента или шаблона.

Файл result_modifier.php - инструмент для модификации данных работы компонента произвольным образом. Создается разработчиком самостоятельно.

Если в папке шаблона есть файл result_modifier.php, то он вызывается перед подключением шаблона и если в нем изменить массив $arResult, то измененный массив перейдет в файл шаблона. Таким образом удобно модифицировать стандартные компоненты Битрикс без вмешательства в них. В дальнейшем такой подход позволяет обновлять не только ядро Битрикс, но и само решение. При обновлении файл result_modifier.php не будет затронут.
Приведенный выше код, как раз предназначен для файла result_modifier.php.
Но поскольку у нас уже модифицированный шаблон, то нет особого смысла усложнять решение и пользоваться result_modifier.php. Мы разместить преобразование изображения непосредственно в шаблоне компонента списка новостей.
Код ресайза разместим внутри цикла.
Код:
<?foreach($arResult["ITEMS"] as $item):?>
 <?
  $file = CFile::ResizeImageGet($item["PREVIEW_PICTURE"]["ID"],array('width' => 200,'height' => 200), BX_RESIZE_IMAGE_EXACT, true);
  $item["PREVIEW_PICTURE"]['WIDTH'] = $file['width'];
  $item["PREVIEW_PICTURE"]['HEIGHT'] = $file['height'];
  $item["PREVIEW_PICTURE"]['SRC'] = $file['src'];
 ?>


Результат работы будет одинаковый. Расположить код внутри шаблона в данном примере более оптимально т.к. нет ненужного цикла по всему массиву $arResult.

Каталог с ресайзом

Посмотрим результат - уже намного лучше, все карточки одного размера. То, что лица срезались, это изначально картинки выбраны не подходящих пропорций и лучше их автоматически обрезать невозможно.
А чтобы лучше понять, что произошло и как битрикс работает с изображениями предлагаю добавить вывод отладочной информации, в код вывода карточек добавить одну строку (выделил красным).
Код:
        <img class="thumbnail" src="<?=$item['PREVIEW_PICTURE']['SRC']?>">          
        <h5><a href="<?=$item['DETAIL_PAGE_URL']?>"><?=$item['NAME']?></a></h5>
        <p class="price"><b><?=$item['PROPERTIES']['PRICE']['VALUE']?></b></p>
        <p><?=$item['PREVIEW_PICTURE']['SRC']?></p>
        <a href="#" class="button expanded">Купить</a>
Результат будет следующий.

Resize cashe в Битрикс

Обратите внимание Битрикс создает отдельную папку resize_cache в которой сохраняет преобразованные файлы.
 
И остатется вторая проблема - это когда наименование в две строчки у нас сдвигается цена и кнопка купить ниже. Данную проблему мы решим версткой. Зададим фиксированный размер блока вывода наименования таким, чтобы влезало две строки текста.
Код:
.bord h5 {
  display: block;
  height: 60px;
}


Такие CSS стили нужно разместить в основном файле стилей шаблона template_styles.css. Устройство шаблона Битрикс я рассматривал в Уроке 3.

Параметры компонентов Битрикс

Ну а теперь давайте реализуем возможность менять количество колонок товаров  выводимых в каталоге товаров через настройки компонента Битрикс.
Параметры компонента bitrix:news находятся в файле \www\local\templates\startshop\components\bitrix\news\catalog\.parameters.php. Точнее это не параметры самого компонента, а дополнительные параметры которые распространяются на шаблон. Основные параметры лежат в ядре битрикс рядом с кодом компонента. Понять это можно потому, что в коде компонента задается временный массив $arTemplateParameters, который в последствии будет объединен с массивом параметров компонента. А так как у нас шаблон полностью свой, то и типовые параметры нам не нужны, можно их смело очистить и заменить на следующий код.
Код:
<?
if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true) die();

$arTemplateParameters = array(
    "CELL-LARGE" => Array(
        "NAME" => "Количество столбцов для большого экрана",
        "TYPE" => "STRING",
        'DEFAULT' => "5",
    ),
    "CELL-MEDIUM" => Array(
        "NAME" => "Количество столбцов для среднего экрана",
        "TYPE" => "STRING",
        'DEFAULT' => "3",
    ),
    "CELL-SMALL" => Array(
        "NAME" => "Количество столбцов для маленького экрана",
        "TYPE" => "STRING",
        'DEFAULT' => "2",
    ),
);
?>

Параметры компонентов в Битрикс задаются в виде массива ключи, которого являются идентификаторами параметров по которым потом в шаблоне можно будет обратится к массиву $arParams (массив доступный в шаблоне, в который передаются все параметры компонента). Подробнее можно посмотреть в документации Битрикс.
После сохранения файла откроем настройки компонента Новости и в параметрах перейдем в раздел Дополнительные настройки. В нем будут доступны наши добавленные настройки.

Дополнительные параметры компонента Битрикс

Т.к. шаблон адаптивный мы внесли параметры для трех размеров экранов. Т.е. у нас будет возможность на каждом размере экрана задать какое количество столбцов нужно выводить.
Теперь посмотрим, как это реализовать в шаблоне?

Код:
<?
$largeup = 'large-up-'.$arParams['CELL-LARGE'];
$mediumup = 'medium-up-'.$arParams['CELL-MEDIUM'];
$smallup = 'small-up-'.$arParams['CELL-SMALL'];

$div_class = $smallup.' '.$mediumup.' '.$largeup;

?>

<div class="grid-x grid-padding-x <?=$div_class?>">
    
<?foreach($arResult["ITEMS"] as $item):?>

Этот код нужно вставить перед циклом. (Строку цикла второй раз повторять не нужно уже.)
Рассмотрим, что мы делаем этим кодом? Мы берем из параметров компонента значения количества колонок для каждого из размеров экрана и формируем три CSS класса large-up-5 medium-up-3 small-up-2. Далее для удобства мы их собираем в одну строку и добавляем к основному блоку DIV. Строка у нас получится следующая <div class="grid-x grid-padding-x small-up-2 medium-up-3 large-up-5">. Это легко проверить посмотрев исходный код страницы в браузере.
Вот такой прием обычно используют когда нужно из компонента повлиять на верстку страницы.

Передача параметров между компонентами Битрикс

Если теперь мы сохраним шаблон и обновим страницу, то ожидаемого результата не получим. А наоборот вся верстка у нас слетит. Как же так, вроде все сделали правильно? Но есть один нюанс, на который не сразу обратишь внимание. Дело в том, параметры мы добавили к компоненту News. А вывод на страницу у нас происходит через компонент news.list. По этому параметры установленные для компонента новости не доступны в списке новостей. Чтобы это исправить, нужно самостоятельно добавить эти параметры от комплексного компонента к простому. Для этого нужно в файле комплексного компонента \www\local\templates\startshop\components\bitrix\news\catalog\news.php дописать передачу параметров в блок вызова компонента списка новостей.
Код:
<?$APPLICATION->IncludeComponent(
    "bitrix:news.list",
В конец массива передаваемых параметров компоненту допишем три наших новых параметра.
Код:
$APPLICATION->IncludeComponent(
    "bitrix:news.list",
    "",
    Array(
        "IBLOCK_TYPE" => $arParams["IBLOCK_TYPE"],
        "IBLOCK_ID" => $arParams["IBLOCK_ID"],
        "NEWS_COUNT" => $arParams["NEWS_COUNT"],
        "SORT_BY1" => $arParams["SORT_BY1"],
        "SORT_ORDER1" => $arParams["SORT_ORDER1"],
        "SORT_BY2" => $arParams["SORT_BY2"],
        "SORT_ORDER2" => $arParams["SORT_ORDER2"],
        "FIELD_CODE" => $arParams["LIST_FIELD_CODE"],
        "PROPERTY_CODE" => $arParams["LIST_PROPERTY_CODE"],
        "DETAIL_URL" => $arResult["FOLDER"].$arResult["URL_TEMPLATES"]["detail"],
        "SECTION_URL" => $arResult["FOLDER"].$arResult["URL_TEMPLATES"]["section"],
        "IBLOCK_URL" => $arResult["FOLDER"].$arResult["URL_TEMPLATES"]["news"],
        "DISPLAY_PANEL" => $arParams["DISPLAY_PANEL"],
        "SET_TITLE" => $arParams["SET_TITLE"],
        "SET_LAST_MODIFIED" => $arParams["SET_LAST_MODIFIED"],
        "MESSAGE_404" => $arParams["MESSAGE_404"],
        "SET_STATUS_404" => $arParams["SET_STATUS_404"],
        "SHOW_404" => $arParams["SHOW_404"],
        "FILE_404" => $arParams["FILE_404"],
        "INCLUDE_IBLOCK_INTO_CHAIN" => $arParams["INCLUDE_IBLOCK_INTO_CHAIN"],
        "CACHE_TYPE" => $arParams["CACHE_TYPE"],
        "CACHE_TIME" => $arParams["CACHE_TIME"],
        "CACHE_FILTER" => $arParams["CACHE_FILTER"],
        "CACHE_GROUPS" => $arParams["CACHE_GROUPS"],
        "DISPLAY_TOP_PAGER" => $arParams["DISPLAY_TOP_PAGER"],
        "DISPLAY_BOTTOM_PAGER" => $arParams["DISPLAY_BOTTOM_PAGER"],
        "PAGER_TITLE" => $arParams["PAGER_TITLE"],
        "PAGER_TEMPLATE" => $arParams["PAGER_TEMPLATE"],
        "PAGER_SHOW_ALWAYS" => $arParams["PAGER_SHOW_ALWAYS"],
        "PAGER_DESC_NUMBERING" => $arParams["PAGER_DESC_NUMBERING"],
        "PAGER_DESC_NUMBERING_CACHE_TIME" => $arParams["PAGER_DESC_NUMBERING_CACHE_TIME"],
        "PAGER_SHOW_ALL" => $arParams["PAGER_SHOW_ALL"],
        "PAGER_BASE_LINK_ENABLE" => $arParams["PAGER_BASE_LINK_ENABLE"],
        "PAGER_BASE_LINK" => $arParams["PAGER_BASE_LINK"],
        "PAGER_PARAMS_NAME" => $arParams["PAGER_PARAMS_NAME"],
        "DISPLAY_DATE" => $arParams["DISPLAY_DATE"],
        "DISPLAY_NAME" => "Y",
        "DISPLAY_PICTURE" => $arParams["DISPLAY_PICTURE"],
        "DISPLAY_PREVIEW_TEXT" => $arParams["DISPLAY_PREVIEW_TEXT"],
        "PREVIEW_TRUNCATE_LEN" => $arParams["PREVIEW_TRUNCATE_LEN"],
        "ACTIVE_DATE_FORMAT" => $arParams["LIST_ACTIVE_DATE_FORMAT"],
        "USE_PERMISSIONS" => $arParams["USE_PERMISSIONS"],
        "GROUP_PERMISSIONS" => $arParams["GROUP_PERMISSIONS"],
        "FILTER_NAME" => $arParams["FILTER_NAME"],
        "HIDE_LINK_WHEN_NO_DETAIL" => $arParams["HIDE_LINK_WHEN_NO_DETAIL"],
        "CHECK_DATES" => $arParams["CHECK_DATES"],
        
             "CELL-LARGE" => $arParams["CELL-LARGE"],
            "CELL-MEDIUM" => $arParams["CELL-MEDIUM"],
            "CELL-SMALL" => $arParams["CELL-SMALL"],
    ),
    $component
);

Я их выделил красным. Вот теперь после сохранения каталог будет работать как нужно. Будет работать адаптивность и через настройки можно менять количество выводимых колонок.

Адаптивный каталог StartShop

Архив магазина StartShop на момент урока можно скачать отсюда.


От автора:
Ну вот, наконец-то мы доделали наш каталог для магазина Битрикс на редакции Старт StartShop. Теперь он выглядит вполне достойно, можно редактировать количество выводимых элементов, количество колонок. Он адаптивный - меняет количество колонок в зависимости от размера экрана. Конечно, над красотой каталога можно ещё работать и работать, но это уже выходит за рамки моего курса (по крайней мере пока). А в следующим уроке мы займемся выводом детальной страницы товара.
Давайте обратную связь и подписывайтесь, чтобы не пропустить новые статьи. До встречи.