Битрикс. Введение в кастомизацию

20.05.2015
@LEXXX_NF

Disclaimer

Сегодня, разбирая хлам в Dropbox’е, я обнаружил эту статью, которую написал в 2010 году для корпоративного блога компании, в которой я тогда работал. Блог не состоялся, я больше Битриксом не занимаюсь и статья пропадает зря. Возможно, в чём-то она уже не актуальна, но, думаю, что основные принципы программирования на Битриксе за 4 года не изменились. Поэтому публикую статью здесь в надежде, что кому-нибудь пригодиться.

Введение

Коробка с БитриксомВ своей работе — а я занимаюсь разработкой сайтов на платформе 1С-Битрикс — мне довольно часто приходится иметь дело с проектами, разработанными другими людьми. И в этих проектах регулярно встречаются настолько грязные хаки, инъекции и вообще кривой код, что удивляешься, как оно до сих пор работает. Раньше я не понимал, почему люди так не любят битрикс; почему говорят, что он медленно работает; почему для работы с сайтом на битриксе нужны знания HTML и PHP, ведь там почти всё сделано удобно и красиво. Теперь я начинаю понимать:)

В этом материале я хотел бы немного рассказать о принципах программирования для битрикса, точнее о 3 столпах разработки проектов на битриксе: шаблонах, компонентах, модулях. Зная, что это такое, можно разработать любой проект: и сайт-визитку с суперуникальным ни на что не похожим дизайном и мощный web-сервис с огромной посещаемостью. Причем они будут радовать своих посетителей скоростью работы (насколько это возможно для битрикса), а своих владельцев — удобством работы и поддержки. В статье я буду часто употреблять слово «кастомизация», как синоним «разработки», при этом имея в виду вообще заточку того или иного механизма под нужды конкретного проекта.

План статьи таков:

  1. рассмотрим вкратце шаблоны, компоненты и модули;
  2. посмотрим, на что они способны в плане кастомизации, коснёмся особых случаев;
  3. приведём примеры.

Компоненты

Компоненты БитриксаМеханизм компонентов не самый простой и не самый часто кастомизуемый, но я решил начать именно с него, потому что он является ядром логики проекта, именно он определяет, как всё вертится и работает. На сайте битрикса написано, что компонент — это «логически завершенный код, … принимающий ряд параметров, выполняющий ряд действий и выводящий какой-либо результат». Знакомым с архитектурой MVC компонент может показаться похожим на контроллер и это действительно так. На вход компонент принимает массив параметров, на выходе отдаёт шаблону массив данных, а в процессе работы использует API модулей. Бесспорно, самый часто употребляемый компонент — список новостей. И это не потому, что на сайтах много новостей, а потому, что этим компонентом удобно выводить любые списки: будь то статьи, отзывы, FAQ или топ товаров. Другими примерами компонентов могут быть: компонент авторизации, корзины, меню.

Поскольку битрикс — это система со многими точками входа и реально существующими файлами страниц, размещать компоненты нужно именно в этих файлах. Так же компоненты могут быть размещены в шаблонах сайта (чем они отличаются от шаблонов компонентов, я расскажу ниже) или во включаемых областях. Таким образом из компонентов собираются страницы, а из страниц — сайт.

Шаблоны

Шаблоны в битриксе, как и во многих других системах, выполняют функцию отображения данных. Как я уже говорил, компонент передаёт в шаблон массив данных, а задача шаблона — преобразовать этот массив в удобоваримый вид, например, в HTML-код. Шаблоны — это самый простой и самый часто используемый способ кастомизации.

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

Помнишь, дорогой читатель, про самый часто употребляемый компонент — список новостей? Он такой универсальный как раз благодаря шаблонам. Именно они позволяют превратить список файлов для скачивания в фотогалерею, а фотогалерею — в отзывы партнёров.

Модули

Модули БитриксаВ простейшем случае модуль — это класс или набор классов, методы которого формируют API для использования в компонентах. Обычно, вместе с модулем поставляется некоторый набор компонентов. Например, с модулем поиска мы получаем такие компоненты как: Облако тегов, Стандартная страница поиска, Форма поиска и др. Количество и состав модулей, входящих в стандартную поставку, зависит от редакции битрикса. Разумеется, с каждым компонентом поставляется минимум один шаблон.

Ну вот про основы я рассказал и, перед тем как перейти к кастомизации, хочу обратить внимание на 2 принципа разработки под битрикс:

  1. Никаких запросов к базе данных! Про существование БД вообще лучше забыть и пользоваться только возможностями, предоставляемыми API модулей. Сами производители платформы мотивируют это тем, что они могут изменить формат БД в любой момент и из-за этого сайт перестанет работать. Единственный случай, когда можно использовать прямые запросы к БД — это обращение к таблицам, созданным непосредственно вами.
  2. Нельзя изменять системные файлы, включая стандартные шаблоны, компоненты, модули. Дело в том, что всё это может быть затёрто ближайшим обновлением и всё труды пойдут насмарку. Можно создать свои с нуля или скопировав готовые и изменять уже их.

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

Кастомизация

Самая лучшая кастомизация — это отсутствие кастомизации. Почему? Потому что, написав свой код, его придётся поддерживать: исправлять в нём баги, закрывать дыры и наращивать функционал. Зачем делать лишнюю работу, если можно её свалить на плечи разработчиков битрикса? Таким образом, если можно ограничиться только настройками существующего — ограничиваемся ими, если нет — читаем статью дальше.

Самое простое, что можно сделать в целях кастомизации — изменить шаблон. Компонент на выходе выдаёт огромную гору данных, из которых можно много чего соорудить. Для изменения внешнего вида, не затрагивающего логику, этот способ подходит лучше всего.

Например, хотим в шапке на главной устроить слайдшоу из нескольких картинок. Нет ничего проще! Нужно завести для картинок отдельный инфоблок, а затем вывести их стандартным компонентом новостей. Хранить картинки удобнее всего в свойстве «картинка для анонса», так как оно поддерживает автоматическое масштабирование. Для этого компонента нужно сделать специальный шаблон, который будет формировать HTML для картинок. В этом же шаблоне на картинки натравливаем какой-нибудь jQuery’вский плагин для слайдшоу — всё готово.

Уже в этом месте можно остановиться и обратить внимание на ошибки. Многие прожженные программеры, которым поставят задачу сделать слайдшоу, решат её так: зальют в какую-нибудь папочку на серваке картинки, а на странице воткнут соответствующий HTML-код и вызов jQuery-скрипта. Задача выполнена, заказчик счастлив. Геморрой начнётся тогда, когда понадобится сделать второе такое слайдшоу, поменять картинки или сделать картинки ссылками. Чтобы это сделать, придётся позовать того же программера, который сделает второе такое же слайдшоу. Я конечно утрирую, и большинство разумных и не слишком ленивых программеров решит задачу правильно, но и с такими случаями я тоже сталкивался.

Внимание, нюанс! Если вы, как и я, везде включаете кэширование и подключаете скрипты не прямо HTML-кодом, а используете отложенную функцию «AddHeadScript», то вас поджидает сюрприз. При включенном кэшировании скрипт не будет подключаться. Это и логично, ведь результат работы компонента закэшировался и никакие функции вызываться не будут. На наше счастье, в последних версиях битрикса появился файлик component_epilog.php, который вызывается после работы шаблона и не кэшируется.

А теперь представим, что у нас на сайте 5 слайдшоу, которые отличаются спецэффектом перехода между картинками, временем показа каждой, ну и разумеется показываются разные картинки, причем для некоторых из них могут быть указаны ссылки, чтобы при клике на картинку переходить куда-нибудь. Давайте накопипастим 5 шаблонов! Это метод экстенсивный, поэтому мы пойдём другой путёй. Шаблоны компонентов могут иметь свои настройки, как и сами компоненты. Ничто не мешает нам вынести в них и эффекты переходов, и длительности, и вообще, все, что угодно. А что делать с самими картинками и ссылками? Во-первых, элементы инфоблока можно организовывать в иерархические секции-папки. Если сделать по одной для каждого слайдшоу, то это решит первую проблему. Во-вторых, инфоблоки для того и существуют, чтобы у их элементов было много разных свойст. Так что ссылки можно хранить в отдельном свойстве. Вот теперь заказчик счастлив, потому что сам может и картинки загружать и эффекты выбирать.

К слову, параметризованных шаблонов я почти не встречал. Странно, что люди не пользуются таким удобным методом.

А теперь еще усложним задачу, вплотную подведя её к грани разумного. Представим, что ссылки на слайдах, про которые я уже говорил, ведут на страницы новостей. Трувейно будет не хранить сами URL ссылок и текст для них, а хранить ID новости, на которую должна вести ссылка. Проблема в том, что наш расчудесный шаблон не знает ничего про новость, кроме её номера. Что же делать? А почему бы прямо в шаблоне не воспользоваться API и не выбрать саму новость по ID, а уж там у этой новости найдётся и название и URL и всё, что душе угодно. Но мы же хорошие программеры, мы не будем месить логику и преставление в одну кучу. Злой гений подсказывает мне, что есть другой выход. И действительно, те, кто внимательно курил мануалы по битриксу, знают про файл «result_modifier.php», в котором разработчики битрикса рекомендуют проводить всякие манипуляции с результатом вывода компонента. В нём доступны те же массивы, что и в шаблоне, но выполняется он до шаблона, а результат его работы кэшируется вместе со всем выводом компонента. Именно в этом файле нам надо выбрать новости, используя API модуля инфоблоков, и записать результат в общий массив вывода компонента. В файле шаблона нам будет доступен уже модифицированный массив.

Как бы еще извратиться с этим слайдшоу? Давайте сделаем его разным для разных регионов посетителей сайта. Например так: некоторые картинки показываются всем регионам, а некоторые — «региональные» — только конкретным, такой вот гео-таргетинг. Регион у пользователей будет храниться в cookie. Разумеется, для хранения принадлежности картинки к тому или иному региону, мы заведём в инфоблоке соответствующее свойство. Можно пойти уже знакомой дорожкой и выбрать сразу все картинки, а в файл result_modifier.php отфильтровать только нужные. Но зачем нам ворочать лишними массивами данных, ведь мы собираем быстрый сайт! Итак, возможности шаблона по модификации данных исчерпаны и пришло время делать свой компонент. Начинается все с того, что копируется стандартный компонент в наше собственное пространство имён и там модифицируется. В нашем случае достаточно добавить в компонент дополнительную фильтрацию — это даже не строчка, это — пол строчки. Но глупо было бы делать свой компонент и остановиться на этом месте. Пожалуй, вторая из двух основных причина, из-за которых прибегают к кастомизации компонентов, — это скорость. Стандартные компоненты слишком универсальны, поэтому они громоздки и медлительны. Почему бы нам не выкинуть функционал, которым мы заведомо не будем пользоваться в данном проекте? Тем более что мы его всегда сможем подглядеть в стандартном компоненте, ведь он остался нетронутым.

Ну вот мы и рассмотрели методы кастомизации, которые покроют 99% всех нужд. Ради оставшегося процента придётся писать свой модуль. Мне всего пару раз приходилось прибегать к этому. В обоих случаях мне требовалось создавать свои таблицы в БД, поэтому это был разумный выход. Вообще, модули — это сущности битрикса, которые поддерживают инсталляцию и деинсталляцию. Поэтому их используют не только для доступа к БД и создания уникального API, но еще и просто для дистрибуции наборов компонентов и шаблонов, которые можно устанавливать и удалять в пару кликов.

Я обещал коснуться особых случаев. Как я уже говорил, страницы в битриксе — это реально существующие файлы, поэтому никто не мешает писать PHP-код прямо в них. Многие, очень многие этим злоупотребляют! Что может быть проще, чем прямо на странице нахардкодить нужный функционал? Зачем заморачиваться с какими-то компонентами, копировать туда-сюда шаблоны? А я скажу зачем! Во-первых, мало кто догадается свой код снабдить системой кэширования. А в компонентах она уже есть. Во-вторых, как весь этот код контнет-менеджеру править через визуальный редактор? Ну и в-третих, это очень тяжело поддерживать.

Однако существует один случай, когда можно кодить прямо на странице. Помнишь, когда мы писали свой компонент для слайдшоу? Так вот эту же задачу можно было решить, задав фильтр для стандартного компонента. Фильтр как раз и будет тем кодом, который нужно написать на странице перед вызовом компонента. Он мал и прост, поэтому визуальный редактор не сойдёт с ума при встрече с ним.

Примеры

Приведу несколько примеров решений, к которым мне пришлось прибегнуть в ходе разработки одного интернет-магазина.

Задача: вывести в тег title не только название текущей страницы, но и список всех родительских разделов в обратном порядке вплоть до корня.
Решение: вставить в тег title компонент навигационной цепочки с кастомизованным шаблоном.

Задача: сделать 2 списка новостей: для главной страницы — со ссылкой на все новости, для внутренней — с пагинатором. Позже задача расширилась: надо было точно таким же образом оформить акции компании, новые решения и советы.
Решение: сделать параметризованный шаблон. В параметры попадают названия блоков и текст ссылки на все новости (акции, советы и т. п.) Шаблон очень легко и просто расширяется.

Задача: вывести в корзине полное описание товаров.
Решение: кастомизовать шаблон. Нужную выборку сделать в файле «result_modifier.php».

Задача: вывести форму авторизации в попапе.
Решение: кастомизовать шаблон.

Задача: сделать так, чтобы в списке товаров по умолчанию отображались все свойства инфоблоков, кроме тех, что начинаются с «_».
Решение: кастомизовать компонент.

Задача: сделать так, чтобы можно было оставлять отзывы и оценки на товары. Предусмотреть возможность премодерации.
Решение: написать новый модуль.

Заключение

Хорошие разработчики и программеры не почерпнули из статьи ничего нового, плохие — вспомнили свои ошибки и забили на них, остальные — намотали на ус

#1
Дмитрий
26.11.2016 08:14
Хорошая статья, актуальна до сих пор.

Писáть здесь

А еще у меня есть: