«В жизни всё когда-нибудь случается в первый раз…»
Капитан Очевидность
Перед любым начинающим разработчиком сайтов с использованием системы управления контентом «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)» → «Копировать шаблон компонента»:
Придумываем имя для шаблона компонента, выбираем место его хранения и жмём «Сохранить»:
Появится код шаблона компонента:
Как с ним работать? Тут каждый выбирает сам.
-
Можно, конечно, и данном окне, но это крайне неудобно.
-
Можно кликнуть на ссылку «Редактировать файл в панели управления» и работать оттуда − тоже так себе вариант.
-
Можно просто скопировать код и открыть его в своей среде разработки, модифицировать и скопировать обратно.
-
Наконец, можно подключиться к серверу, на котором лежит сайт по 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 файлы шаблона модифицируемого компонента – они нам не пригодятся.
При кастомизации шаблона компонента таким образом мы просто должны заменить модифицированным компонентом сегмент вёрстки (он приведен выше), отвечающий за меню. Для этого в публичной части жмём «Изменить страницу»:
Затем в открывшемся окне выбираем режим редактирования исходного кода и копируем код вызова компонента:
Нам остаётся только заменить скопированным кодом компонента сегмент кода верстки отвечающем за меню.
Результат:
Да, и не забудьте удалить с тестовой страницы компонент меню :)