1. Главная
  2. Блог
  3. 1С-Битрикс
  4. Кастомизация шаблона компонента

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

18 Сентября 2019
14


«В жизни всё когда-нибудь случается в первый раз…»

Капитан Очевидность


Перед любым начинающим разработчиком сайтов с использованием системы управления контентом «1С-Битрикс» рано или поздно (скорее всего рано) встанет задача по изменению существующих в «1С-Битрикс» компонентов.

И, вот, наступает этот ответственный момент — потеют ладони, учащается пульс, лоб покрывается холодной испариной, в голове роятся вопросы — как не ошибиться, «не уронить» сайт, «не пролететь мимо» техподдержки «1С-Битрикс»? 

Всё вышеперечисленное (и многое другое) действительно мешает сосредоточиться на разработке. Как же не «наломать дров»? Давайте разбираться.

Сперва оговоримся, что речь в данной статье пойдет об изменении («кастомизации») именно шаблона компонента. То есть о преобразовании его визуального представления, а не об изменении логики его работы. «Кастомизацию» самого компонента (как простого, так и комплексного) мы опишем в одной из следующих статей, а сейчас мы обсудим изменение его внешнего вида. Тем более, что подобная задача встаёт перед разработчиками гораздо чаще... А решить её гораздо проще :)

Изменять внешний вид компонентов приходится при интеграции верстки любого сайта. Дизайнер нарисовал сайт, верстальщик создал макет, а разработчику надо заставить всё это работать. Ведь практически в любом сайте есть:

  • несколько видов меню, 

  • строка поиска, 

  • авторизация 

  • и много чего ещё. 

Для правильного функционирования всех этих элементов в «1С-Битрикс» есть набор различных компонентов (меню, «хлебные крошки», каталог и т.п.), но внешний вид компонентов из коробки будет сильно отличаться от того, что было придумано творческой натурой дизайнера.

Сперва несколько правил

Первое
Свой собственный кастомизированный шаблон сайта мы храним в папке /local/ в корне сайта. Если такой папки там нет — создаем и переносим туда наш шаблон сайта. Битрикс работает таким образом, что у папки /local/ всегда будет приоритет выше, чем у папки /bitrix/, таким образом если в /local/templates/ и /bitrix/templates/ будут лежать шаблоны с одинаковыми названиями будут выполняться шаблоны из /local/templates/. Подобный подход к работе — активное использование папки /local/ — позволяет нам отделить свой код от кода разработчиков «1С-Битрикс». 

Второе
Мы не изменяем сам компонент из коробки, да система вам скорее всего не позволит это сделать, мы копируем компонент и будем работать уже с его копией . 

Третье
Ни под каким соусом мы не лезем в ядро «1С-Битрикс» ( особенно в папку /bitrix/modules/) — начинающему разработчику (а вы — начинающий разработчик, иначе зачем вы читаете эту статью?) нечего там делать. 

Четвёртое
На всякий случай перед кастомизацией делаем бэкап — подробности ниже. Соблюдение всех этих правил позволит нам не «поломать сайт», не остаться без помощи техподдержки и, что очень важно, не потерять все свои разработки при обновлении версии «1С-Битрикс».

Начнём с начала − Бэкап

В режиме Администрирования идём:

Настройки → Инструменты → Резервное копирование → Создание резервной копии

Выбираем место хранения резервной копии. В облаке «1С-Битрикс» предпочтительней, если зарезервированной там памяти хватает для создании копии. Либо в папке сайта − при выборе этого варианта убедитесь, что на хостинге достаточно места для хранения резервной копии и функционирования сайта, иначе сайт просто «ляжет».  Жмём кнопку «Создать резервную копию». После этого можно почти безбоязненно экспериментировать с сайтом, по крайней мере если у вас есть к нему доступ по ssh или ftp :)


Начинаем кастомизацию шаблона компонента

Давайте для примера кастомизируем что-нибудь очень нужное и не очень простое. Пожалуй, компонент «Меню» отлично подойдет.

Допустим, меню по задумке дизайнера должно выглядеть так:



Но компонент к которому применен встроенный шаблон может выглядеть, например, так:



Давайте приведем его к требуемому виду. Для этого из публичного раздела создадим тестовую страницу − все эксперименты сперва будем ставить на ней.



Вводим название для заголовка страницы, имени файла, снимаем галку «Добавить пункт меню» и жмём “Готово”:



Оказавшись на нашей тестовой странице, жмём «Изменить страницу» → «В визуальном редакторе»



Появляется окно редактирования страницы. В нем сперва выбираем режим отображения «Визуальный режим» (1), затем в поисковой строке (2) пишем «меню», выбираем компонент «Меню» (3) и, зажав левую кнопку мыши, перетаскиваем его в рабочую область (4):



После этого откроются параметры компонента. Если почему-то не открылись, просто дважды кликните левой кнопкой мыши по выбранному компоненту. Установим стандартные настройки компонента как показано на рисунке:



Дважды жмём «Сохранить» и компонент отображается на нашей тестовой странице:


Для дальнейшей работы в правом верхнем углу окна браузера должен быть включен режим правки:



В режиме правки наводим указатель мышки на наш компонент, в появившемся меню жмём на треугольник рядом с шестерёнкой, затем «Меню (bitrix:menu)» → «Копировать шаблон компонента»:



Придумываем имя для шаблона компонента, выбираем место его хранения и жмём «Сохранить»:



Появится код шаблона компонента:



Как с ним работать? Тут каждый выбирает сам. 

  1. Можно, конечно, и данном окне, но это крайне неудобно. 

  2. Можно кликнуть на ссылку «Редактировать файл в панели управления» и работать оттуда − тоже так себе вариант. 

  3. Можно просто скопировать код и открыть его в своей среде разработки, модифицировать и скопировать обратно. 

  4. Наконец, можно подключиться к серверу, на котором лежит сайт по ssh или ftp. 

Я предпочитаю использовать среду разработки Visual Studio Code − это достаточно мощный и совершенно бесплатный инструмент. Его фишка (при установке соответствующего плагина) − возможность подключиться к серверу по ssh и работать с файлами сайта напрямую. Но тут каждый поступает, как ему удобнее. В любом случае, вот код шаблона компонента меню:



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

	<?if (!empty($arResult)):?>
	<ul id="horizontal-multilevel-menu">
	<?
	$previousLevel = 0;
	foreach($arResult as $arItem):?>
           
	  <?if ($previousLevel && $arItem["DEPTH_LEVEL"] < $previousLevel):?>
	     <?=str_repeat("</ul></li>", ($previousLevel - $arItem["DEPTH_LEVEL"]));?>
	  <?endif?>
               
	  <?if ($arItem["IS_PARENT"]):?>
	     
             <?if ($arItem["DEPTH_LEVEL"] == 1):?>
	        <li><a href="<?=$arItem["LINK"]?>" class="<?if ($arItem["SELECTED"]):?>root-item-selected<?else:?>root-item<?endif?>"><?=$arItem["TEXT"]?></a>
	          <ul>
	     <?else:?>
	        <li<?if ($arItem["SELECTED"]):?> class="item-selected"<?endif?>><a href="<?=$arItem["LINK"]?>" class="parent"><?=$arItem["TEXT"]?></a>
	          <ul>
	     <?endif?>
           
	  <?else:?>
	    <?if ($arItem["PERMISSION"] > "D"):?>
            
	      <?if ($arItem["DEPTH_LEVEL"] == 1):?>
	        <li><a href="<?=$arItem["LINK"]?>" class="<?if ($arItem["SELECTED"]):?>root-item-selected<?else:?>root-item<?endif?>"><?=$arItem["TEXT"]?></a></li>
 	      <?else:?>
	        <li<?if ($arItem["SELECTED"]):?> class="item-selected"<?endif?>><a href="<?=$arItem["LINK"]?>"><?=$arItem["TEXT"]?></a></li>
	      <?endif?>
              
	    <?else:?>
                  
	       <?if ($arItem["DEPTH_LEVEL"] == 1):?>
	         <li><a href="" class="<?if ($arItem["SELECTED"]):?>root-item-selected<?else:?>root-item<?endif?>" title="<?=GetMessage("MENU_ITEM_ACCESS_DENIED")?>"><?=$arItem["TEXT"]?></a></li>
	       <?else:?>
	         <li><a href="" class="denied" title="<?=GetMessage("MENU_ITEM_ACCESS_DENIED")?>"><?=$arItem["TEXT"]?></a></li>
	       <?endif?>
              
	    <?endif?>
          
          <?endif?>
           
	  <?$previousLevel = $arItem["DEPTH_LEVEL"];?>
          
	<?endforeach?>
         
	<?if ($previousLevel > 1)://close last item tags?>
	  <?=str_repeat("</ul></li>", ($previousLevel-1) );?>
	<?endif?>
	</ul>
         
	<div class="menu-clear-left"></div>
	<?endif?>

А вот верстка нашего меню:


        <div class="nv_topnav">
	  <ul>
	    <li><a href=""><span></span></a></li>
	    <li><a href=""><span>Компания</span></a>
              <ul>
	        <li><a href="">Пункт 1</a></li>
                <li><a href="">Пункт 2</a></li>
                <li><a href="">Пункт 3</a></li>
                <li><a href="">Пункт 4</a></li>
	      </ul>
            </li>
            <li><a href=""><span>Новости</span></a></li>
            <li><a href=""><span>Каталог</span></a></li>
            <li><a href=""><span>Акции</span></a>
              <ul>
                <li><a href="">Пункт 1</a>
	          <ul>
                    <li><a href="">Пункт 1</a></li>
                    <li><a href="">Пункт 2</a></li>
	          </ul>
	        </li>
                <li><a href="">Пункт 2</a></li>
                <li><a href="">Пункт 3</a></li>
                <li><a href="">Пункт 4</a></li>
              </ul>
            </li>
            <li><a href=""><span>Партнерам</span></a></li>
            <li><a href=""><span>Контакты</span></a></li>
            <div class="clearboth"></div>
          </ul>
        </div>

Если при просмотре кода страницы возникли проблемы с обнаружением требуемого элемента верстки, то открываем html страницу в браузере и при помощи инструмента разработчика находим искомый элемент кода. Например, в браузере Google Chrome жмём кнопку на клавиатуре F12, потом кликаем на элемент, выделенный на скриншоте ниже красным, затем на меню. После этого нам остаётся найти этот же сегмент в коде:




На первый взгляд, код шаблона компонента меню может показаться страшным и непонятным, но присмотревшись к нему повнимательнее мы замечаем, что его html структура (что неудивительно) довольно похожа на нашу вёрстку.

Меню представляет собой таблицу заключёную в теги <ul></ul>, только в шаблоне <ul> имеет id, а вёрстке нет. Кроме того в вёрстке <ul></ul> обернуты тегами <div></div> с классом "nv_topnav". 

Посмотрев на строки таблицы, ещё мы заметим, что в вёрстке, в отличие от шаблона меню, текст внутри тегов <a></a> обернут в <span></span>. 

Заметим, что в вашем случае вёрстки отличия будут иными, но принцип останется тем же. Нам нужно лишь преобразовать код шаблона компонента в соответствии с нашей вёрсткой – убрать лишний id у <ul>, обернуть всю таблицу в <div>, добавить <span> в строки таблицы. В результате получим такой код:


	<?if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();?>
	<?if (!empty($arResult)):?>
           <div class="nv_topnav">
              <ul>
	      <?
	      $previousLevel = 0;
              foreach($arResult as $arItem):?>
                  
                 <?if ($previousLevel && $arItem["DEPTH_LEVEL"] < $previousLevel):?>
	            <?=str_repeat("</ul></li>", ($previousLevel - $arItem["DEPTH_LEVEL"]));?>
	         <?endif?>
                             
	         <?if ($arItem["IS_PARENT"]):?>
                    
	            <?if ($arItem["DEPTH_LEVEL"] == 1):?>
	               <li><a href="<?=$arItem["LINK"]?>" <?if(isset($arItem["PARAMS"]["IMG"])):?>class="menu-img-fon" style="background-image: url(/bitrix/templates/.default/images/nv_home.png);"<?endif;?>><span><?=$arItem["TEXT"]?></span></a>
	                  <ul>
                    <?else:?>
                       <li><a href="<?=$arItem["LINK"]?>" ><?=$arItem["TEXT"]?></a>
                          <ul>
                    <?endif?>
                         
	         <?else:?>
                         
                    <?if ($arItem["PERMISSION"] > "D"):?>
                       <?if ($arItem["DEPTH_LEVEL"] == 1):?>
                          <li><a href="<?=$arItem["LINK"]?>"<?if(isset($arItem["PARAMS"]["IMG"])):?> class="menu-img-fon" style="background-image: url(/bitrix/templates/.default/images/nv_home.png);"<?endif;?>><span><?=$arItem["TEXT"]?></span></a></li>
                       <?else:?>
                          <li><a href="<?=$arItem["LINK"]?>"><?=$arItem["TEXT"]?></a></li>
                       <?endif?>
                       
                    <?endif?>
                         
                 <?endif?>
                            
                 <?$previousLevel = $arItem["DEPTH_LEVEL"];?>
                          
              <?endforeach?>
                         
              <?if ($previousLevel > 1)://close last item tags?>
                 <?=str_repeat("</ul></li>", ($previousLevel-1) );?>
              <?endif?>
              <div class="clearboth"></div>
             
           </ul>
        </div>
     <?endif?>

Обратите внимание, на то, что в условии <?if ($arItem["PERMISSION"] > "D"):?> мы удалили <?else:?>, т.к. в нашем примере отсутствует проверка на права доступа к элементам меню.

Предполагается, что css файл со стилями нашей вёрстки уже подключен к шаблону нашего сайта, так что мы можем смело удалять css файлы шаблона модифицируемого компонента – они нам не пригодятся.

При кастомизации шаблона компонента таким образом мы просто должны заменить модифицированным компонентом сегмент вёрстки (он приведен выше), отвечающий за меню. Для этого в публичной части жмём «Изменить страницу»:



Затем в открывшемся окне выбираем режим редактирования исходного кода и копируем код вызова компонента:



Нам остаётся только заменить скопированным кодом компонента сегмент кода верстки отвечающем за меню.

Результат:


Да, и не забудьте удалить с тестовой страницы компонент меню :)


8 800 201-07-68
Консультации по решению