Структура страницы
В системе «Битрикс: Управление сайтом» страница представляет из себя PHP файл, состоящий из пролога, тела страницы и эпилога.
В общем случае структура страницы выглядит как:
Благодаря технологии отложенных функций часть визуальных элементов выводимых в прологе может быть задана в теле страницы, это такие элементы как:
- заголовок страницы (выводится функцией CMain::ShowTitle)
- навигационная цепочка (выводится функцией CMain::ShowNavChain)
- CSS стили (выводятся функцией CMain::ShowCSS)
- Мета-тэги (выводятся функцией CMain::ShowMeta)
- и др.
Принципиальной особенностью данной технологии является то, что она позволяет отложить исполнение некоторых функций, выполняя их в эпилоге, а результаты их выполнения подставляя в вышележащий код.
Но есть ряд задач которые не могут быть решены с помощью технологии отложенных функций. Это относится к случаям когда необходимо производить какие либо действия в прологе над значениями которые в предыдущем примере задавались бы в теле страницы (например, свойства страницы). В этом случае возникает необходимость разбить пролог на служебную и визуальную части и эти значения задавать между ними. Достигается это следующим образом:
В служебной части пролога происходит подключение к базе, отработка агентов, инициализация служебных констант, проверка прав уровня 1, подключение необходимых модулей, исполнение обработчиков событий OnPageStart, OnBeforeProlog, а также ряд других необходимых действий. Особенностью служебной части пролога является то, что она не выводит никаких данных (не посылает header браузеру).
В визуальной части пролога происходит подключение файла , где ID шаблона сайта — идентификатор текущего шаблона сайта. Данный файл хранит левую верхнюю часть текущего шаблона сайта.
В свою очередь и эпилог может быть разбит на визуальную и служебную части:
В визуальной части эпилога происходит подключение файла , где ID шаблона сайта — идентификатор текущего шаблона сайта. Данный файл хранит правую нижнюю часть текущего шаблона сайта. Помимо этого — выводится ряд невидимых IFRAME’ов используемых технологией переноса посетителей.
В служебной части эпилога происходит отправка почтовых сообщений, исполнение обработчиков события OnAfterEpilog, отключение от базы, а также ряд других служебных действий.
Зачастую возникают задачи когда нет необходимости в подключении визуальной частей пролога и эпилога (например, при использовании редакции «Битрикс: Веб-аналитика»). В этом случае достаточно подключить служебные части пролога и эпилога:
Для корректной работы системы, обязательным являются подключения служебных частей пролога и эпилога.
Juggernaut. Единая точка входа
В статье рассматривается альтернативный способ загрузки страниц т. н. «Единая точка входа» (иначе FrontController). Его сравнение с текущим способом загрузки ну и конечно реализация данного подхода.
Все что описано ниже, это мое личное мнение и виденье, если оно вас не устраивает, если вы считаете меня не компетентным, или недостаточно опытным — это сугубо ваше личное мнение. Если говорить про объективную критику и советы — то милости прошу, это очень даже полезные штуки, тем более что именно для них и написана статья. Ну, а теперь поехали
Так уж случилось, что по каким-то причинам Битрикс не имеет единую точку входа.
Не то, чтобы это было прям необходимо, но ДА — это прям необходимо!
Почему же единая точка прям таки нужна (прям таки для Битрикс):
- облегчает управление приложение
- делает прозрачным порядок обработки запроса
- избавляет от include вообще (да-да)
- позволяет много чего интересного (об этом ниже)
ЗАГРУЗКА СТРАНИЦЫ (by Bitrix)
Рассмотрим порядок загрузки страницы Битрикс ( http://dev.1c-bitrix.ru/api_help/main. eplan.php) :
- Подключение /bitrix/php_interface/dbconn.php (различные константы)
- Соединение с базой данных
- Подключение /bitrix/php_interface/after_connect.php
- Определение текущего сайта (определяются все классы и функции Главного модуля с учетом выбранного сайта)
- Подключение /bitrix/php_interface/init.php
- Подключение /bitrix/php_interface/SITE_ID/init.php
- Проверка агентов
- Открытие сессии
- Событие OnPageStart
- Определение пользователя, авторизация пользователя, завершение сеанса, регистрация (в зависимости от параметров в запросе)
- Определение текущего шаблона сайта
- Событие OnBeforeProlog
- Проверка прав доступа уровня 1
- Начало буфферизации вывода
- Событие OnProlog
- Подключение /bitrix/templates/ID шаблона сайта/header.php
- Обработка страницы
- Подключение /bitrix/templates/ID шаблона сайта/footer.php
- Вызов функции Cmain::ShowSpreadCookieHTML (данная функция выводит набор невидимых IFRAME’ов используемых в Технология переноса посетителей)
- Событие OnEpilog
- Завершение буферизации страницы
- Отправка E-Mail писем
- Событие OnAfterEpilog
- Завершение соединения с базой данных
Ну а теперь небольшой разбор всего того что выше (если какие то пункты опущены, то значит по ним нет комментариев):
2-3. а зачем подключаться сразу? Если мы хотим вернуть статику (кеш) это действие будет лишним;
7. проверка, то есть запуск? Вообще немного странно, но про агенты будет далее;
8. опять лишнее действие если данные в сессии не хранятся (хотя по факту Битрикс ее юзает в любом случае, но по идее стартовать должен модуль ее использующий, и это не должно быть заложено априори);
16-21. самое непонятное что может только быть. То есть если нам нужно вывести при обработке страницы, что-либо в шаблоне (title, breadcrumbs, установка заголовков, . ) мы прекращаем текущую буферизацию, запоминаем данные, а затем начинаем буферизацию по новой и по сути загрузка страницы может выглядит примерно так:
22. почему отдельно, а не в пункте 23?
Собственно опущены очевидные вещи и все то что касается многосайтовости.
ЗАГРУЗКА СТРАНИЦЫ (by Juggernaut)
Для начала нужно составить порядок загрузки страницы:
- Событие OnInit (конструктор)
- Событие OnBeforeRequest
- Обработка запроса
- Событие OnAfterRequest
- Отправка ответа (вместе с заголовками, куками и данными)
Теперь конкретно по пунктам:
- OnInit – в данном событии определяются константы, обработчики событий и какой сайт запрашивается (собственно сначала нужно делать это, а потом уже все остальное).
- OnBeforeRequest – сюда можно посадить например выполнение агентов.
- Обработка запроса — определение нужно действия, обработка ошибок и прочие полезности.
- OnAfterRequest – сюда можно посадить например логирование, выполнение агентов (хотя лучше не стоит, ниже подробнее).
- Отправка ответа — собственно вот
Чем проще тем лучше господа!
Прежде чем я перейду к профитам данного порядка загрузки, представлю псевдокод (концепт) который собственно данный порядок формализует и добавляет некоторые возможности:
Реализация классов Request, Response и др. опущена, потому что не имеет особо значения (на данный момент по крайней мере).
Какие плюсы вытекают из «нового» варианта загрузки:
- это проще и прозрачнее
- избавляет от глобальных переменных типа APPLICATION, USER, …
- упрощает подключение файлов и модулей
- все страницы, можно вынести из публичной части
- избавляет от AddBufferContent и ее логики коллбэков
- нет include (вообще)
- …
На самом деле это все, что пришло в голову, но мне достаточно 1 пункта.
Вот такой небольшой вариант альтернативной загрузки, ваши вопросы, предложения, пожелания и гневные комменты жду ниже
Порядок подключения стилей шаблонов Битрикс
Заметил что стили шаблона подключаются позже стилей страницы, а именно в таком порядке:
- page_f86d7559f17b653dfba993517abd9fd3_v1.css?1634846341275
- template_styles.css
Возникает вопрос, правильно ли это?
Ведь сначала должны быть общие стили, а потом уже стили страницы. Может я на какой то из страниц захочу переопределить стиль, и в такой ситуации это будет невозможно.
Тоже столкнулся с данной проблемой.
Она на самом деле шире чем просто порядок подключения файлов.
Попробую расписать подробнее суть проблемы.
Проблема №1
Как мы на проекте выполняем подключение стилей шаблона:
Общие стили шаблона мы подключаем с использованием главного модуля через Asset.
Также у нас есть стили компонентов, которые битрикс подключает автоматически.
Но внутри компонентов может понадобиться подключить другие стили.
Например в данном случае мы подключаем стили и скрипты Swiper.
Также подключаем их с использованием главного модуля через Asset в component_epilog.php.
Хорошо, очевидно, что вторым параметром мы передаём false во всех случаях подключения стилей.
Если мы подключим дополнительные стили компонента и стили страницы с параметром true — они попаду в файл template_336e9cf2eed8f19d39118eb918a64a21_v1.css?164432234555761.
И мы увидим следующий порядок стилей в template_336e9cf2eed8f19d39118eb918a64a21_v1.css?164432234555761
Проблема №3
Так сказать вишенка на торте: проблема с порядком подключения файлов актуальна исключительно для CSS!
А проблема с порядком сборки файлов актуальна и для CSS и для JS файлов.
Содержимое файла page_51e5d331108e789163bdd0926b2ddde7_v1.js?1644321931142197:
Т.е. сперва включаются скрипты страницы, потом скрипты компонента размещённого на ней и уже в самом конце скрипты которые мы дополнительно подключили в компоненте.
В случае JS проблема не так очевидна, так как мы обычно дожидаемся готовности документа через $( document ).ready() или DOMContentLoaded.
Как должно быть:
Админы/Р азработчики Битрикс, как прокомментируете и что посоветуете?
Коллеги кто и как решает данный вопрос?
Битрикс. Файл init.php
Сам по себе файл не обязательный, особенность его в том, что он подключается в начале каждой страницы сайта и служит для инициализации обработчиков событий или подключения дополнительных функций. То есть, в нем можно размещать код, который необходим для выполнения на каждой странице сайта.
Последовательность очереди подключения можно посмотреть в документации по Битрикс: первым идет подключение пролога, а затем init.php .
Если в системе несколько сайтов, то можно создать отдельную директорию для каждого сайта с индивидуальным init.php . Имя каждой директории совпадает с ID сайта. Первым подключается файл из директории bitix/php_interface , а потом — из bitix/php_interface/ID .
Кроме того, файл init.php может быть создан в директории local/php_interface или в директории local/php_interface/ID . Если такие файлы есть, они будут использованы вместо файлов в директории bitrix . Это директория как раз и нужна для того, чтобы ничего не менять в ядре Битрикс. Битрикс в первую очередь смотрит local и только если файлы не найдены, ищет их в bitrix .
Если файл init.php будет создан в директории bitrix/php_interface , то в случае ошибки в коде, весь сайт перестанет работать, в том числе и админка (т.е. через админку исправить ошибку не получится). Если файл будет создан в директории bitix/php_interface/ID , то в случае ошибки кода, сайт перестанет работать, но админку это не затронет, и через панель управления можно будет внести правки в init.php .
Если файл bitrix/php_interface/init.php содержит ошибки, получаем белый экран и текст:
Зайти в панель управления и иcправить ошибку теперь нельзя. Чтобы избежать такой ситуации, надо вынести содержимое файла init.php в отдельный файл и подключить его другим способом.
В подключаемом файле допущена ошибка, нет ; после функции define() :
Но, набрав в адресной строке
можно не подключать файл с ошибкой и получить доступ к панели управления. И уже в панели управления исправить ошибку.
Порядок подключения стилей шаблонов Битрикс
Заметил что стили шаблона подключаются позже стилей страницы, а именно в таком порядке:
- page_f86d7559f17b653dfba993517abd9fd3_v1.css?1634846341275
- template_styles.css
Возникает вопрос, правильно ли это?
Ведь сначала должны быть общие стили, а потом уже стили страницы. Может я на какой то из страниц захочу переопределить стиль, и в такой ситуации это будет невозможно.
Тоже столкнулся с данной проблемой.
Она на самом деле шире чем просто порядок подключения файлов.
Попробую расписать подробнее суть проблемы.
Проблема №1
Как мы на проекте выполняем подключение стилей шаблона:
Общие стили шаблона мы подключаем с использованием главного модуля через Asset.
Также у нас есть стили компонентов, которые битрикс подключает автоматически.
Но внутри компонентов может понадобиться подключить другие стили.
Например в данном случае мы подключаем стили и скрипты Swiper.
Также подключаем их с использованием главного модуля через Asset в component_epilog.php.
Хорошо, очевидно, что вторым параметром мы передаём false во всех случаях подключения стилей.
Если мы подключим дополнительные стили компонента и стили страницы с параметром true — они попаду в файл template_336e9cf2eed8f19d39118eb918a64a21_v1.css?164432234555761.
И мы увидим следующий порядок стилей в template_336e9cf2eed8f19d39118eb918a64a21_v1.css?164432234555761
Проблема №3
Так сказать вишенка на торте: проблема с порядком подключения файлов актуальна исключительно для CSS!
А проблема с порядком сборки файлов актуальна и для CSS и для JS файлов.
Содержимое файла page_51e5d331108e789163bdd0926b2ddde7_v1.js?1644321931142197:
Т.е. сперва включаются скрипты страницы, потом скрипты компонента размещённого на ней и уже в самом конце скрипты которые мы дополнительно подключили в компоненте.
В случае JS проблема не так очевидна, так как мы обычно дожидаемся готовности документа через $( document ).ready() или DOMContentLoaded.
Как должно быть:
Админы/Р азработчики Битрикс, как прокомментируете и что посоветуете?
Коллеги кто и как решает данный вопрос?