Иногда перед контент-менеджерами стоит задача выводить в произвольной части статьи какой-нибудь интерактивный элемент, например слайдер или фотогалерею с возможностью увеличить изображение нажатием мышки. При этом контент-менеджер часто не обладает навыками вёрстки, которые позволили бы ему ограничится готовым сниппетом сладера или галереи и инструмента «медиабиблиотека». Удобный вариант такой вставки реализован в WordPress, когда в плагине фотогалереи менеджер может загрузить и отредактировать формат подготовленные фотографии, а в тело статьи в нужном месте вставить специальный код например [gallary_123] где 123 — это уникальный идентификатор той фотогалереи которую он только что создал и наполнил. Такой формат мы и реализуем на 1С Битрикс «Управление сайтом».

Создадим инфоблок фотогалерий

Итак, у меня установлено коробочное решение, «Мебельная компания» на основе редакции «Старт», на момент написания статьи, версия ядра 18.1.5. Создаём инфоблок со следующими основными настройками:

Настройка инфоблока

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

Настройка доступа

Во вкладке «Доступ» устанавливаем «Чтение» для всех пользователей, чтобы наши фотографии могли видеть все посетители сайта просматривающие новость с фотогалереей. Затем добавляем единственное свойство «Фотографии».

Свойство - Фотографии

Свойство должно быть множественным т.к. фотографий в галерее у нас может быть сколько угодно, а так же обязательным к заполнению (мы ведь не можем выводить пустую фотогалерею).

Дополнительные настройки свойства фотографии

В дополнительных настройках свойства «Фотографии» необходимо отметить флажок «Выводить поле для описания значения», это нужно для того, чтобы контент-менеджер мог описать загружаемое изображение и позже пользователь мог видеть это описание при просмотре галереи. Та же я рекомендую ограничить тип загружаемых файлов, будем позволять грузить только изображение, защита от дурака так сказать. Инфоблок готов к использованию.

Давайте создадим тестовый элемент галереи для одной из существующих новостей и закинем несколько фотографий найденных в Google по запросу «выставка мебели», у меня получилось следующее:

Тестовый элемент галереи

Если кто-то не знает как задать описание фотографии, щёлкните по значку карандаша под фото и во всплывающем окне заполните поле «Описание» вот так:

Описание фотографии

Можно готовить компонент галереи.

Готовим шаблон компонента фото-галереи

Т.к. наша галерея основана на инфоблоке, самым очевидным компонентом для её показа будет обычная детальная страница новости т.е. bitrix:news.detail. Создадим тестовый раздел и разместим там компонент  bitrix:news.detail, компонент необходимо настроить на работу с только что созданным инфоблоком «Фотогалерея», отключить все параметры устанавливающие заголовки и описания страницы, отключить показ всевозможных доп.свойств типа дата изменения элемента, детальное описание и т.п.

В свойстве «ID новости» можно сразу указать ID тестовой галереи, в моём случае это 33, это нужно для удобства настройки шаблона. В параметрах компонента в поле «Свойства», свойство MORE_PHOTO нужно указать вручную, его не будет в списке доступных свойств инфоблока т.к. это свойство типа «Файл»:

Свойство типа Файл

Обязательно отключите режим Ajax в параметрах компонента!
Базовые настройки сделаны, можно сохранять и копировать шаблон компонента для последующей кастомизации. Я скопировал шаблон компонента bitrix:news.detail в дефолтный шаблон сайт и назвал его gallary, вам советую сделать так же чтобы не запутаться в дальнейшем:

Кастомизация шаблона компонента

В качестве плагина для фотогалереи я предлагаю использовать всем хорошо знакомый Fancybox, который можно скачать с официального сайта http://fancyapps.com/fancybox/3/ в последней версии этот плагин предоставляет очень симпатичное оформление фотогалереи прямо из коробки.

Что необходимо подключить:

  • последнюю стабильную минифицированную версию JQuery
  • сам плагин jquery.fancybox.min.js
  • стили jquery.fancybox.min.css

Подключаем, файлы я предварительно раскидал по папкам css и js внутри папки шаблон /bitrix/templates/furniture_gray/


<?
//Где-то вначале 
use Bitrix\Main\Page\Asset;
 
//и в блоке header
//Подключаем и выводим CSS
Asset::getInstance()->addCss(SITE_TEMPLATE_PATH. '/css/jquery.fancybox.min.css' );
 
//Подключаем пользовательские и выводим стандартные js скрипты
Asset::getInstance()->addJs(SITE_TEMPLATE_PATH."/js/jquery-3.2.1.min.js");
Asset::getInstance()->addJs(SITE_TEMPLATE_PATH."/js/jquery.fancybox.min.js");

Теперь необходимо настроить сам шаблон. Идём в папку с шаблоном, у меня это /bitrix/templates/.default/components/bitrix/news.detail/gallary/ , здесь необходимо создать файл result_modifier.php в котором предварительно подготовить картинки к показу в галереи.

<? if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true) die();
	//Предварительно готовим картинки
	if($arResult['PROPERTIES']['MORE_PHOTO']['VALUE']){
		$photos = [];
		foreach ($arResult['PROPERTIES']['MORE_PHOTO']['VALUE'] as $key => $photoId) {
			$arPhoto = CFile::ResizeImageGet($photoId, ["width" => 150, "height" => 150], BX_RESIZE_IMAGE_EXACT, true, false, false, 100);
			$arPhotoBig = CFile::ResizeImageGet($photoId, ["width" => 800, "height" => 600], BX_RESIZE_IMAGE_PROPORTIONAL, true, false, false, 100);
			$photos[] = ['SRC'=>$arPhoto['src'], 'SRC_BIG' => $arPhotoBig['src'], 'ALT'=>$arResult['PROPERTIES']['MORE_PHOTO']['DESCRIPTION'][$key]];
		}
 
		//И сохраняем в кеш только нужные данные
		$arResult['GALLARY_PHOTOS'] = $photos;
		$this->__component->SetResultCacheKeys(['GALLARY_PHOTOS']);
	}

Всегда используйте конструкцию $this->__component->SetResultCacheKeys([‘CUSTOM_PROPERTY_KEY’]); для кеширования данных в result_modifier.php, так вы будете хранить в кеше строго-ограниченные данные, не переполняя его, чем сэкономите память и повысите быстродействие сайта.
И сам шаблон template.php:

<?if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();
 
$this->setFrameMode(true);
if($arResult['GALLARY_PHOTOS']) { //А есть ли вообще картинки?>
 
	<div class="gallary">
		<? foreach ($arResult['GALLARY_PHOTOS'] as $key => $photo) { ?>
			<div class="gallary_item">
				<a href="<?=$photo['SRC_BIG'];?>" class="fancybox" data-fancybox="images" data-caption="<?=$photo['ALT'];?>" >
					<img src="<?=$photo['SRC'];?>" alt="<?=$photo['ALT'];?>">
				</a>
			</div>
		<? } ?>
	</div>
 
<? } ?>

Если вы всё подключили правильно галерея уже начнёт работать. Давайте добавим немного красоты путём стилизации наших классов gallary и gallary_item и изображений внутри. Для универсальности предлагаю использовать файл стилей компонента галереи. Пропишем следующий стиль:
.gallary {
	display: flex;
	flex-direction: row;
	justify-content: space-between;
}

.gallary_item {
	overflow: hidden;
	position: relative;
}

.gallary_item img {
	width: 100%;
	height: auto;
	max-width: 100%;
	display:block;
	-webkit-transition:all 0.2s ease-out;
	-moz-transition:all 0.2s ease-out;
	-o-transition:all 0.2s ease-out;
	-ms-transition:all 0.2s ease-out;
	transition:all 0.2s ease-out;
}

.gallary_item:hover img {
	-webkit-transform:scale(1.1);
	-moz-transform:scale(1.1);
	-o-transform:scale(1.1);
	-ms-transform:scale(1.1);
	transform:scale(1.1);
}
Получается примерно такой эффект:
Стиль галереи
Внешний вид галереи после применения стилей. В реальности эффект более плавный
Ну что же, компонент готов, теперь можно заняться его вставкой в детальный текст элемента инфоблока, например новостной статьи.

Вставка галереи в тело статьи

Для начала нам нужно кастомизировать компонент news.detail новостного раздела, не важно отдельный это компонент или входит в состав комплексного. Нам потребуется отредактировать файл result_modifier.php, template.php и component_epilog.php, начнём с result_modifier.php.

Первым делом скопируйте шаблон компонента на основе которого сделан раздел новостей, в моём случае это комплексный компонент bitrix:news, копируем шаблон компонента в дефолтный шаблон сайта, я назвал его news_block.  Далее идём в папку компонент news.detail, т.е.  /bitrix/templates/.default/components/bitrix/news/news_block/bitrix/news.detail/.default/ и создаём файлыresult_modifier.php иcomponent_epilog.php. В result_modifier.php необходимо добавить следующий код для кеширования шаблона.


<? if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();
 
//Кешируем данные после обновления буфера шаблона
$this->__component->SetResultCacheKeys(array("CACHED_TPL")); ?>

В файл component_epilog.php нужно вставить специальную конструкцию, которая будет искать в теле статьи «хеш-тег» #GALLARY_ID_123# где 123 — идентификатор галереи (элемента инфоблока) и подгружать на его место компонент галереи (который мы ранее настроили) с переданным в него ID-шником 123. Весь код выглядит так:

<?if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();

//Заменяем хеш-тег GALLARY_ID на компонент
echo preg_replace_callback(
        "/#GALLARY_ID_([\d]+)#/is".BX_UTF_PCRE_MODIFIER,
        create_function('$matches', 'ob_start();
		$GLOBALS["APPLICATION"]->IncludeComponent("bitrix:news.detail", "gallary", Array(
			"ACTIVE_DATE_FORMAT" => "d.m.Y",
				"ADD_ELEMENT_CHAIN" => "N",
				"ADD_SECTIONS_CHAIN" => "N",
				"AJAX_MODE" => "N",
				"AJAX_OPTION_ADDITIONAL" => "",
				"AJAX_OPTION_HISTORY" => "N",
				"AJAX_OPTION_JUMP" => "N",
				"AJAX_OPTION_STYLE" => "N",
				"BROWSER_TITLE" => "-",
				"CACHE_GROUPS" => "N",
				"CACHE_TIME" => "36000000",
				"CACHE_TYPE" => "A",
				"CHECK_DATES" => "N",
				"DETAIL_URL" => "",
				"DISPLAY_BOTTOM_PAGER" => "N",
				"DISPLAY_DATE" => "N",
				"DISPLAY_NAME" => "N",
				"DISPLAY_PICTURE" => "N",
				"DISPLAY_PREVIEW_TEXT" => "N",
				"DISPLAY_TOP_PAGER" => "N",
				"ELEMENT_CODE" => "",
				"ELEMENT_ID" => $matches[1],	// ID галереи найденный в теге #GALLARY_ID_xxx#
				"FIELD_CODE" => array(
					0 => "",
					1 => "",
				),
				"IBLOCK_ID" => "5", //Код инфоблока галери
				"IBLOCK_TYPE" => "news", //Тип инфоблока
				"IBLOCK_URL" => "",
				"INCLUDE_IBLOCK_INTO_CHAIN" => "N",
				"MESSAGE_404" => "",
				"META_DESCRIPTION" => "-",
				"META_KEYWORDS" => "-",
				"PAGER_BASE_LINK_ENABLE" => "N",
				"PAGER_SHOW_ALL" => "N",
				"PAGER_TEMPLATE" => ".default",
				"PAGER_TITLE" => "Страница",
				"PROPERTY_CODE" => array(	// Свойства
					0 => "",
					1 => "MORE_PHOTO",
					2 => "",
				),
				"SET_BROWSER_TITLE" => "N",
				"SET_CANONICAL_URL" => "N",
				"SET_LAST_MODIFIED" => "N",
				"SET_META_DESCRIPTION" => "N",
				"SET_META_KEYWORDS" => "N",
				"SET_STATUS_404" => "N",
				"SET_TITLE" => "N",
				"SHOW_404" => "N",
				"STRICT_SECTION_CHECK" => "N",
				"USE_PERMISSIONS" => "N",
				"USE_SHARE" => "N",
			),
			false
		);
         $retrunStr = @ob_get_contents();
         ob_get_clean();
         return $retrunStr;'),
         $arResult["CACHED_TPL"]);
?>


Обратите внимание что вместо привычного $APPLICATION использовано $GLOBALS[«APPLICATION»], это нужно для видимости объекта внутри временной функции. Так же обратите внимание на $matches[1] это динамический параметр передаваемый в параметры вызова компонента news.detail, в нём содержится ID галереи.
Осталось поправить файл шаблона template.php, на второй сточке, сразу после проверки обращения к файлу пишем код:

<? ob_start(); ?>

а в конце кода пишем:


<?
$this->__component->arResult["CACHED_TPL"] = @ob_get_contents();
ob_get_clean();
?>


Манипуляции с component_epilog.php сделаны чтобы обойти кеширование. Как вы уже поняли весь этот «финт» основан на манипуляции буфера вывода.

Вместо заключения

Теперь ваш контент-менеджер может без труда вставлять фото-галереи прямо в тело статьи и ему не нужно разбираться в вёрстке и стилях. Порядок действия теперь такой:

  1. Создание галереи в инфоблоке галерей, после сохранения менеджер запоминает ID элемента инфоблока ( в моём случае это ID 33)
  2. В нужном месте детального описания новости (инфоблок новости) необходимо вставить следующий код #GALLARY_ID_33#
Вставка галереи в тело статьи
Вставка галереи в тело статьи в форме редактирования элемента инфоблока. И вот результат:
Результат вставки галереи
Я думаю не надо объяснять что так можно вставлять что угодно, слайдеры, формы опроса, товарные предложения и т.д. Желаю удачи!

Полезная статья?
(Голосов: 2, Рейтинг: 3.44)
Вам также могут понравиться
Объективно о преимуществах и недостатках 1С-Битрикс

Объективно о преимуществах и недостатках 1С-Битрикс

С развитием интернета появилось много платформ, которые помогают начинающим бизнесменам создать и сделать рентабельным и успешным интернет-магазин. Но подобрать действительно эффективную площадку не так-то просто. Что необходимо знать, чтобы не прогореть, какой тип платформы выбрать. Об этом поговорим в этой статье.

Авторизация на сайте при помощи Вконтакте

Авторизация на сайте при помощи Вконтакте

Большинство социальных сетей позволяют использовать свои API для авторизации пользователей на сайте имеющих аккаунт в данной социальной сети. В статье рассмотрен способ авторизации при помощи API вконтакте.ру.

Исключения в PHP, что это и как ими пользоваться

Исключения в PHP, что это и как ими пользоваться

В этой статье вы узнаете что такое исключения в PHP и как их использовать для обработки ошибок. Начиная с PHP версии 5.0 стала доступна новая модель обработки ошибок, так называемые исключения. Она позволяет более гибко и информативно для пользователя обрабатывать не стандартные ситуации в работе вашего приложения. 


Комментарии
Защита от автоматических сообщений
CAPTCHA
Введите слово на картинке
17.04.2020 | Антон

Огромное спасибо!

Комментировать | 0  
Защита от автоматических сообщений
CAPTCHA
Введите слово на картинке
Закрыть
18.05.2020 | Анрей

Супер! Спасибо большое автору, все получилось (хотя и не с первого раза) и прекрасно работает! Не заострено внимание на том, что в файле "component_epilog.php" нужно поменять на свои значения тип инфоблока ("IBLOCK_TYPE" => "news", //Тип инфоблока ) и код инфоблока галереи ("IBLOCK_ID" => "5", //Код инфоблока галери"), ну и сложные компоненты иногда не так разложены по подпапкам, как тут описано, но все-таки разобраться можно. ЕЩЕ РАЗ ОГРОМНАЯ БЛАГОДАРНОСТЬ!

Комментировать | 0  
Защита от автоматических сообщений
CAPTCHA
Введите слово на картинке
Закрыть
19.05.2020 | maler1988

Рад был помочь! Спасибо за обратную связь! Учту эти моменты и допишу в статью.

Комментировать | 0  
Защита от автоматических сообщений
CAPTCHA
Введите слово на картинке
Закрыть
04.07.2020 | Никита

Спасибо за решение! А как быть если таким образом нужно вывести не 1 а 2 разных компонента, например?

Комментировать | 0  
Защита от автоматических сообщений
CAPTCHA
Введите слово на картинке
Закрыть
28.07.2020 | maler1988

Здравствуйте. Нужно будет добавить ещё один "хеш-тег" и вызов preg_replace_callback() в component_epilog.php

Комментировать | 0  
Защита от автоматических сообщений
CAPTCHA
Введите слово на картинке
Закрыть