Не пропусти свежие посты, подпишись:
Иногда перед контент-менеджерами стоит задача выводить в произвольной части статьи какой-нибудь интерактивный элемент, например слайдер или фотогалерею с возможностью увеличить изображение нажатием мышки. При этом контент-менеджер часто не обладает навыками вёрстки, которые позволили бы ему ограничится готовым сниппетом сладера или галереи и инструмента «медиабиблиотека». Удобный вариант такой вставки реализован в 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#
Вставка галереи в тело статьи
Вставка галереи в тело статьи в форме редактирования элемента инфоблока. И вот результат:
Результат вставки галереи
Я думаю не надо объяснять что так можно вставлять что угодно, слайдеры, формы опроса, товарные предложения и т.д. Желаю удачи!

Не пропусти свежие посты, подпишись:
Полезная статья?
(Голосов: 4, Рейтинг: 3.66)
Курсы от партнёров
Хотите освоить востребованную профессию? Воспользуйтесь предложениями от наших партнёров. Пройдите учебный курс по одному из популярных IT направлений.

Все курсы партёнров
Вам также могут понравиться
Кем можно работать в сфере веб-разработки

Кем можно работать в сфере веб-разработки

Хотите начать работать в сфере веб-разработки, но не знаете с чего можно начать? Читайте описание самых популярных веб-профессий, с их описанием, обязанностями и ориентировочными зарплатами.

CSS курсоры

CSS курсоры

В статье рассмотрены возможности изменения курсоров пользователя при помощи CSS

Работа с регистром строк в php

Работа с регистром строк в php

В статье рассмотрены примеры работы с регистром строк в языке PHP, проверка регистра, изменение, инверсия


Комментарии
Защита от автоматических сообщений
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
Введите слово на картинке
Закрыть