В коробочном Битрикс24 можно добавить собственный пункт в структуру мобильного меню через PHP-обработчик события onMobileMenuStructureBuilt.
Это удобно, когда нужно открыть внутреннюю мобильную страницу портала: тикеты, заявки, отчеты, инструкции или отдельный мини-интерфейс для сотрудников.
В статье разберём рабочий подход на примере пункта IQTicket, который открывает страницу /mobile/iqticket/index.php.
Создаем PHP-класс CCustomMobileMenu, который добавляет свои группы и пункты в массив мобильного меню.
Подключаем класс через Loader::registerAutoLoadClasses в local/php_interface/init.php.
Вешаем обработчик на событие mobile:onMobileMenuStructureBuilt.
Добавляем страницу, которую будет открывать пункт меню.
Проверяем URL, авторизацию, права доступа, кеш и отображение пункта в мобильном приложении.
Пример структуры на сервере:
Название файла класса лучше держать таким же, как название класса: CCustomMobileMenu.php. Так проще не запутаться в автозагрузке.
Файл:
/local/php_interface/init.php<?php
use Bitrix\Main\Loader;
Loader::registerAutoLoadClasses(null, [
'CCustomMobileMenu' => '/local/php_interface/classes/CCustomMobileMenu.php',
]);
AddEventHandler(
'mobile',
'onMobileMenuStructureBuilt',
['CCustomMobileMenu', 'onMobileMenuStructureBuilt']
);Если в init.php уже есть открывающий тег <?php, второй раз его добавлять не нужно. Просто вставьте use Bitrix\Main\Loader;, регистрацию автозагрузки и AddEventHandler.
Не стоит делать отдельный класс под каждый пункт. Удобнее держать один универсальный класс и описывать группы и пункты в массиве конфигурации.
Файл:
/local/php_interface/classes/CCustomMobileMenu.php<?php
class CCustomMobileMenu
{
private const GROUPS = [
[
'id' => 'custom_tools',
'title' => 'Рабочие инструменты',
'sort' => 300,
'hidden' => false,
'items' => [
[
'id' => 'iqticket_mobile',
'title' => 'IQTicket',
'url' => '/mobile/iqticket/index.php',
'sort' => 10,
'hidden' => false,
'color' => '#8E52EC',
'imageUrl' => '/bitrix/js/mobile/images/settings.png',
'cache' => false,
'useSearchBar' => false,
],
],
],
// [
// 'id' => 'reports',
// 'title' => 'Отчеты',
// 'sort' => 360,
// 'hidden' => false,
// 'items' => [
// [
// 'id' => 'reports_mobile',
// 'title' => 'Отчеты',
// 'url' => '/mobile/reports/index.php',
// 'sort' => 10,
// 'hidden' => false,
// 'color' => '#2FC6F6',
// 'imageUrl' => '/bitrix/js/mobile/images/plus.png',
// 'cache' => false,
// 'useSearchBar' => false,
// ],
// ],
// ],
];
public static function onMobileMenuStructureBuilt(array $menu): array
{
foreach (self::GROUPS as $group)
{
if (empty($group['id']) || empty($group['title']) || empty($group['items']))
{
continue;
}
$items = [];
foreach ($group['items'] as $item)
{
if (empty($item['id']) || empty($item['title']) || empty($item['url']))
{
continue;
}
$items[] = [
'id' => $item['id'],
'code' => $item['id'],
'title' => $item['title'],
'sort' => (int)($item['sort'] ?? 100),
'hidden' => (bool)($item['hidden'] ?? false),
'color' => $item['color'] ?? '#2FC6F6',
'imageUrl' => $item['imageUrl'] ?? '/bitrix/js/mobile/images/settings.png',
'attrs' => [
'id' => $item['id'],
'url' => $item['url'],
'cache' => (bool)($item['cache'] ?? false),
'useSearchBar' => (bool)($item['useSearchBar'] ?? false),
],
];
}
if (!$items)
{
continue;
}
$menu[] = [
'id' => $group['id'],
'code' => $group['id'],
'title' => $group['title'],
'sort' => (int)($group['sort'] ?? 100),
'hidden' => (bool)($group['hidden'] ?? false),
'items' => $items,
];
}
return $menu;
}
}Такой вариант удобен тем, что можно хранить несколько групп и несколько пунктов в одном классе. Для нового пункта не нужно копировать обработчик — достаточно добавить элемент в GROUPS.
В классе достаточно добавить новый элемент в items нужной группы. Например, так можно добавить пункт для базы знаний:
[
'id' => 'company_kb',
'title' => 'База знаний',
'url' => '/mobile/kb/index.php',
'sort' => 20,
'hidden' => false,
'color' => '#31C48D',
'imageUrl' => '/bitrix/js/mobile/images/plus.png',
'cache' => false,
'useSearchBar' => true,
],Если нужна отдельная группа, добавьте новый элемент в массив GROUPS:
[
'id' => 'reports',
'title' => 'Отчеты',
'sort' => 360,
'hidden' => false,
'items' => [
[
'id' => 'reports_mobile',
'title' => 'Отчеты',
'url' => '/mobile/reports/index.php',
'sort' => 10,
'hidden' => false,
'color' => '#2FC6F6',
'imageUrl' => '/bitrix/js/mobile/images/plus.png',
'cache' => false,
'useSearchBar' => false,
],
],
],После этого пункт появится в выбранной группе.
Теперь создадим страницу, которую будет открывать пункт меню.
Файл:
/mobile/iqticket/index.php<?php
require($_SERVER['DOCUMENT_ROOT'] . '/mobile/headers.php');
require($_SERVER['DOCUMENT_ROOT'] . '/bitrix/header.php');
global $APPLICATION, $USER;
$APPLICATION->SetTitle('IQTicket');
if (!$USER || !$USER->IsAuthorized())
{
LocalRedirect('/auth/');
}
?>
<div style="padding: 16px; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;">
<div style="background: #fff; border-radius: 16px; padding: 16px;">
<h2 style="margin-top: 0;">Test</h2>
<p style="margin-bottom: 0;">
Мобильная страница открылась внутри приложения Битрикс24.
</p>
</div>
</div>
<?php require($_SERVER['DOCUMENT_ROOT'] . '/bitrix/footer.php'); ?>
Для реального мини-приложения лучше разнести CSS и JS по отдельным файлам:
| Поле | Назначение |
|---|---|
id | Уникальный идентификатор группы или пункта. Лучше использовать стабильный slug. |
code | Уникальный код элемента. В примере он равен id, но у разных пунктов он не должен повторяться. |
title | Название, которое увидит пользователь. |
sort | Порядок группы или пункта. Чем меньше число, тем выше элемент. |
hidden | Если true, группа или пункт будут скрыты. |
color | Цвет плитки или иконки пункта в мобильном меню. |
imageUrl | Путь к изображению иконки. Например, /bitrix/js/mobile/images/settings.png. |
attrs.url | URL страницы, которую нужно открыть. |
attrs.cache | Лучше ставить false для динамических страниц. |
attrs.useSearchBar | Показывать ли поисковую строку в мобильном контейнере. |
В публичном облачном Битрикс24 этот подход не сработает. Он рассчитан на коробочный Битрикс24 или окружение, где есть доступ к PHP-файлам портала.
Для облачного Bitrix24 без доступа к файловой системе нужно использовать возможности REST-приложений и встраивания, а не local/php_interface/init.php.