larikmc / yii2-admin
Unified admin module for Yii2 backend with dashboard, auth and RBAC
Requires
- php: >=8.1
- ext-openssl: *
- yiisoft/yii2: ~2.0
- yiisoft/yii2-bootstrap5: ~2.0
Requires (Dev)
None
Suggests
- bacon/bacon-qr-code: Allows local generation of 2FA TOTP QR codes in SVG format (~2.0)
Provides
None
Conflicts
None
Replaces
None
- dev-master
- v2.1.8
- v2.1.7
- v2.1.6
- v2.1.5
- v2.1.4
- v2.1.3
- v2.1.2
- v2.1.1
- v2.1.0
- v2.0.15
- v2.0.14
- v2.0.13
- v2.0.12
- v2.0.11
- v2.0.10
- v2.0.9
- v2.0.8
- v2.0.7
- v2.0.6
- v2.0.5
- v2.0.4
- v2.0.3
- v2.0.2
- v2.0.1
- v2.0.0
- v1.2.5
- v1.2.4
- v1.2.3
- v1.2.2
- 1.2.1
- 1.1.32
- 1.1.31
- 1.1.30
- 1.1.29
- 1.1.28
- 1.1.27
- 1.1.26
- 1.1.25
- 1.1.24
- 1.1.23
- 1.1.22
- 1.1.21
- 1.1.20
- 1.1.19
- 1.1.18
- 1.1.17
- 1.1.16
- 1.1.15
- 1.1.14
- 1.1.13
- 1.1.12
- 1.1.11
- 1.1.10
- 1.1.9
- 1.1.8
- 1.1.7
- 1.1.6
- 1.1.5
- 1.1.4
- 1.1.3
- 1.1.2
- 1.1.1
- 1.1.0
- 1.0
- dev-feature/skidkum-admin-ui
This package is auto-updated.
Last update: 2026-10-21 08:48:34 UTC
README
Готовое расширение для Yii2 backend: одна установка, один модуль admin, внутри уже есть:
- dashboard и общий layout админки
- авторизация и страница входа
- восстановление пароля для админки
- RBAC: роли, действия и назначения
- одноразовые инвайты для регистрации администратора
- security log
- очистка кеша
- системный bootstrap для
admin,adminPanelи защитных инвариантов root-пользователяID=1
Пакет рассчитан на сценарий, где админка, auth и RBAC живут вместе как единая backend-платформа.
Перед интеграцией UI обязательно прочитайте раздел UI guide в этом README.
Связанные документы:
AI-INTEGRATION-CHECKLIST.md(обязательный чеклист для нейросети при интеграции в новый проект)
Требования
- PHP 8.1+
- Yii2 2.0.x
yiisoft/yii2-bootstrap5authManager=yii\rbac\DbManager
Что дает пакет
После подключения у вас есть:
/admin/admin/login/admin/auth/request-password-reset/admin/auth/reset-password?token=.../admin/auth/invite?token=.../admin/user/profile/admin/site/ui-kit/admin/auth/security-log/admin/rbac/admin/rbac/user/admin/rbac/role/admin/rbac/permission/admin/rbac/assignment/admin/rbac/invite
Внутри RBAC уже поддержана схема:
действия -> роли -> пользователи
То есть:
- создаете действия
- включаете действия в роль
- назначаете роль пользователю
Первоначальная установка и создание администратора
LarikMC Admin обеспечивает максимально простой и быстрый старт в новых проектах:
- Чистая установка: при установке на новый сайт, когда таблица пользователей приложения полностью пуста, первая попытка входа через стандартную форму авторизации (
/admin/login) автоматически создаёт первого администратора. - Как это работает:
- Разработчик открывает
/admin/login, вводит желаемый e-mail и пароль и нажимает «Войти». - Система проверяет, что база пользователей действительно пуста, валидирует данные, безопасно хэширует пароль и создаёт запись в таблице пользователей родительского приложения.
- Автоматически инициализируются таблицы RBAC, создаются роль
adminи разрешениеadminPanel, и роль назначается созданному пользователю. - Пользователь сразу авторизуется и попадает в панель управления. Никаких дополнительных мастеров установки, регистрационных экранов или ручных SQL-запросов не требуется.
- Разработчик открывает
- Безопасность после создания:
- Как только в базе появляется хотя бы один пользователь, механизм автоматической регистрации необратимо отключается.
- Все последующие попытки входа работают строго в режиме аутентификации. Добавление следующих администраторов выполняется исключительно через систему одноразовых приглашений (
/admin/rbac/invite).
- Защита в профиле (2FA):
- После первого входа настоятельно рекомендуется перейти в
/admin/user/profileи подключить двухфакторную аутентификацию (Google Authenticator / TOTP).
- После первого входа настоятельно рекомендуется перейти в
- Отключение автоматической регистрации:
- Если вы хотите полностью запретить создание администратора через форму входа (например, если пользователи импортируются внешним скриптом или сидером), укажите в конфигурации модуля:
'allowFirstAdminRegistration' => false,
- Если вы хотите полностью запретить создание администратора через форму входа (например, если пользователи импортируются внешним скриптом или сидером), укажите в конфигурации модуля:
Warning
ВНИМАНИЕ! Не публикуйте сайт с пустой таблицей пользователей и доступной первоначальной регистрацией администратора. Первый посетитель, отправивший форму входа, сможет получить административные права. Рекомендуется выполнять первоначальную настройку локально или в закрытом окружении и переносить сайт на production уже с созданной учётной записью администратора.
Установка
Composer
composer require larikmc/yii2-admin
После обновления пакета
После composer update (или после переключения версии/тега) рекомендуется:
- очистить опубликованные ассеты Yii (
web/assets/*) - очистить кеш приложения (
php yii cache/flush-all, если команда доступна) - сделать hard refresh в браузере (
Ctrl+F5)
Это нужно, чтобы сразу подтянулись обновленные css/js и новые view-шаблоны расширения.
Для локального path-пакета:
{
"repositories": [
{
"type": "path",
"url": "../yii2-admin",
"options": {
"symlink": true,
"relative": true
}
}
],
"require": {
"larikmc/yii2-admin": "@dev"
}
}
Базовая конфигурация backend
Пример для backend/config/main.php:
'defaultRoute' => 'admin/site/index', 'layout' => '@larikmc/admin/views/layouts/main', 'modules' => [ 'admin' => [ 'class' => larikmc\admin\Module::class, 'userClass' => common\models\User::class, 'userModel' => common\models\User::class, 'userIdField' => 'id', 'usernameField' => 'username', 'emailField' => 'email', 'statusField' => 'status', 'rbacAccessRoles' => [], // Настройки авторизации 'maxUserAttempts' => 5, 'captchaAfterAttempts' => 3, 'lockDuration' => 120, 'userAttemptsTtl' => 120, 'maxDelaySeconds' => 10, // Необязательно: свой placeholder для lazyload. // Если не задано, используется стандартный src/web/img/load.svg из расширения. 'lazyloadPlaceholderUrl' => null, // По умолчанию пакет сам защищает гостя от случайных /admin/... URL // и отправляет на loginUrl. Можно отключить при необходимости. 'guardUnknownAdminRoutesForGuests' => true, // Дополнительные guest-роуты, если в проекте есть свои публичные // backend-страницы внутри /admin. 'guestAllowedPaths' => [], ], ], 'components' => [ 'request' => [ 'baseUrl' => '/admin', ], 'user' => [ 'identityClass' => common\models\User::class, 'enableAutoLogin' => true, 'loginUrl' => ['/login'], ], 'authManager' => [ 'class' => yii\rbac\DbManager::class, ], 'urlManager' => [ 'enablePrettyUrl' => true, 'showScriptName' => false, 'rules' => [ '' => 'admin/site/index', 'admin/error' => 'admin/site/error', 'login' => 'admin/auth/auth/login', 'auth/login' => 'admin/auth/auth/login', 'auth/logout' => 'admin/auth/auth/logout', 'auth/captcha' => 'admin/auth/auth/captcha', 'auth/invite' => 'admin/auth/auth/invite', 'auth/request-password-reset' => 'admin/auth/auth/request-password-reset', 'auth/reset-password' => 'admin/auth/auth/reset-password', 'auth/security-log' => 'admin/auth/auth/security-log', 'auth/clear-security-log' => 'admin/auth/auth/clear-security-log', 'rbac' => 'admin/rbac/default/index', 'rbac/<controller:[\w-]+>' => 'admin/rbac/<controller>/index', 'rbac/<controller:[\w-]+>/<action:[\w-]+>' => 'admin/rbac/<controller>/<action>', 'rbac/<controller:[\w-]+>/<action:[\w-]+>/<id:\d+>' => 'admin/rbac/<controller>/<action>', 'rbac/<controller:[\w-]+>/<action:[\w-]+>/<name:[\w-]+>' => 'admin/rbac/<controller>/<action>', ], ], 'errorHandler' => [ // Обязательно: чтобы 403/404/500 внутри админки рендерились шаблоном расширения. 'errorAction' => '/admin/site/error', ], ],
Примечание по rules: порядок важен. Сохраняйте этот блок целиком, а project-specific правила добавляйте так, чтобы не ломать маршруты auth/* и rbac/*.
Error page (обязательно)
Чтобы использовался шаблон ошибки из расширения (@larikmc/admin/views/site/error.php), в приложении должен быть задан:
'components' => [ 'errorHandler' => [ 'errorAction' => '/admin/site/error', ], ],
Без этого Yii может показывать стандартную страницу ошибки вместо оформленной страницы админки.
Важные пути для входа (рекомендуемый вариант)
Чтобы страница входа открывалась по короткому URL:
https://your-domain/admin/login
используйте такую связку:
request.baseUrl = '/admin'user.loginUrl = ['/login']- правило
urlManager:'login' => 'admin/auth/auth/login' - правило
urlManager:'auth/captcha' => 'admin/auth/auth/captcha'
Пакет сам включает стандартный guest-whitelist для auth/error маршрутов.
Если у вас есть собственная глобальная проверка доступа в on beforeRequest, обязательно добавьте в whitelist:
loginauth/loginauth/captchaauth/request-password-resetauth/reset-passwordauth/inviteadmin/loginadmin/auth/loginadmin/auth/captchaadmin/auth/request-password-resetadmin/auth/reset-passwordadmin/auth/invite
Иначе можно получить цикл редиректов (ERR_TOO_MANY_REDIRECTS) на странице входа.
Защита от случайных /admin/... URL у гостя
Частая интеграционная ошибка:
errorActionуже указывает на/admin/site/error- layout админки уже подключен
- auth-роуты уже проброшены правильно
- но гость всё ещё может открыть случайный несуществующий URL вида
/admin/some-random-path
В таком случае Yii может отрендерить 404 внутри admin-layout, и неавторизованный пользователь увидит sidebar/menu админки.
Начиная с актуальной версии пакет по умолчанию запрещает такие URL для гостя на уровне модуля:
- если гость открывает неразрешенный
/admin/... - пакет вызывает
loginRequired() - и пользователь уходит на
loginUrl, то есть на красивый/admin/login
Если вы хотите поведение как в https://your-domain/admin/login:
- гость открывает корректные auth-страницы
- гость не может открыть произвольный
/admin/... - любой неправильный admin URL у гостя сразу уводит на красивый
/admin/login
обычно ничего дополнительно писать не нужно, если вы используете модуль admin в штатной конфигурации.
При необходимости поведение можно настраивать:
'modules' => [ 'admin' => [ 'class' => larikmc\admin\Module::class, // Отключить встроенный guard полностью 'guardUnknownAdminRoutesForGuests' => false, // Или оставить guard, но расширить whitelist 'guestAllowedPaths' => [ 'upload-photopea/upload', 'admin/upload-photopea/upload', ], ], ],
Если проекту нужен собственный guard на уровне приложения, используйте такой шаблон в backend/config/main.php:
'on beforeRequest' => function () { $app = Yii::$app; $pathInfo = trim((string) $app->request->pathInfo, '/'); $normalizedPath = preg_replace('#^admin/#', '', $pathInfo) ?? $pathInfo; $allowedPaths = [ 'login', 'auth/login', 'auth/logout', 'auth/captcha', 'auth/invite', 'auth/request-password-reset', 'auth/reset-password', 'site/error', 'admin/login', 'admin/auth/login', 'admin/auth/logout', 'admin/auth/captcha', 'admin/auth/invite', 'admin/auth/request-password-reset', 'admin/auth/reset-password', 'admin/site/error', ]; if (in_array($pathInfo, $allowedPaths, true) || in_array($normalizedPath, $allowedPaths, true)) { return; } if ($app->user->isGuest) { $app->user->loginRequired(); $app->end(); } },
Что это дает:
/admin/loginостаётся рабочим коротким URL входа/admin/auth/request-password-resetи/admin/auth/reset-passwordтоже остаются доступными гостю- случайные
/admin/...URL больше не показывают guest-пользователю admin sidebar и внутренний layout - вместо этого Yii отправляет гостя на
loginUrl, то есть на красивый/admin/login
Если вы сознательно отключаете встроенный guard, альтернативный минимальный вариант:
- оставить
errorAction => '/admin/site/error' - и в локальном
SiteControllerпереключать layout ошибки для гостя на auth-layout
Но для production-поведения обычно лучше именно ранний beforeRequest-guard, потому что он не даёт гостю доходить до внутренних admin-ошибок вообще.
Схема доступа
Рекомендуемая схема разделения доступа:
adminPanelдает право войти в админкуadminдает доступ к рабочим backend-контроллерам и административным разделам
То есть:
- пользователь без
adminPanelне должен попадать в/admin - пользователь с
adminPanel, но безadmin, может пройти только уровень входа в админку - backend-контроллеры, dashboard, RBAC и security log должны быть закрыты ролью
admin
Security Model
Матрица доступа по умолчанию:
adminPanel— право пройти в/adminadmin— право работать с backend-контроллерамиadmin— право видеть dashboard и внутренние admin-страницыadmin— право работать с RBACadmin— право просматривать и очищать security log
Коротко:
adminPanel= вход в админкуadmin= вся рабочая часть админки
Меню
Основное меню и нижнее меню задаются через параметры модуля:
menu(основной список ссылок и выпадающих разделов в сайдбаре)secondaryMenu(нижняя карточка в сайдбаре, например showcaseADMIN-UI-KIT)
По умолчанию пакет использует схему:
menu: дашборд + выпадающий разделАдминистрированиес пунктамиRBAC,Инвайт администратораиSecurity LogsecondaryMenu:ADMIN-UI-KIT
Опции элементов меню
Каждый элемент массива menu поддерживает следующие ключи:
| Ключ | Тип | Описание |
|---|---|---|
label |
string |
Текст пункта меню |
icon |
string |
Имя иконки из Google Material Symbols Rounded (например: dashboard, admin_panel_settings, settings, inventory_2) |
url |
array|string |
Маршрут Yii2. Поддерживает маску * в конце пути, например ['/catalog/category/*'] для подсветки раздела на всех подстраницах |
items |
array |
Дочерние элементы. Наличие этого ключа превращает пункт в выпадающую секцию (аккордеон) |
visible |
bool|callable |
Условие отображения пункта (булево значение или анонимная функция fn(): bool) |
active |
bool|callable |
(Опционально) Принудительное указание активного состояния |
open |
bool |
(Опционально) Принудительное раскрытие секции при загрузке страницы |
method |
string |
Метод запроса: 'get' (по умолчанию) или 'post' (рендерит безопасную форму со скрытыми CSRF-полями) |
linkOptions |
array |
Дополнительные HTML-атрибуты для ссылки |
Поведение выпадающих разделов (аккордеон)
- Автоматическое раскрытие активного раздела: когда вы находитесь в каком-либо подразделе (например, RBAC, Инвайты, Security Log или собственный раздел каталога/заказов), родительский пункт меню автоматически раскрыт, его иконка подсвечена, а текущий дочерний пункт выделен.
- Управление авто-раскрытием: поведение регулируется свойством модуля
autoExpandActiveSubmenu(по умолчаниюtrue). При необходимости держать подменю свернутыми установите'autoExpandActiveSubmenu' => false, либо управляйте индивидуально через'open' => true. - Плавная анимация без рывков: раскрытие и сворачивание происходят плавно и стабильно с первого клика (
cubic-bezier(0.4, 0, 0.2, 1)), без рывков («дёргания») верстки и скачков высоты; левая направляющая линия (border-left) плавно растягивается и исчезает синхронно с содержимым. - Аккордеон: при открытии одного раздела другие открытые разделы автоматически плавно сворачиваются, сохраняя сайдбар аккуратным и чистым.
Пример конфигурации меню
'modules' => [ 'admin' => [ 'class' => larikmc\admin\Module::class, 'userClass' => common\models\User::class, 'userModel' => common\models\User::class, 'menu' => [ [ 'icon' => 'dashboard', 'label' => 'Панель управления', 'url' => ['/admin/site/index'], ], [ 'icon' => 'shopping_bag', 'label' => 'Каталог', 'items' => [ ['label' => 'Товары', 'url' => ['/catalog/product/index']], ['label' => 'Категории', 'url' => ['/catalog/category/index']], ], ], [ 'icon' => 'admin_panel_settings', 'label' => 'Администрирование', 'items' => [ ['label' => 'RBAC', 'url' => ['/rbac/default/index']], ['label' => 'Инвайт администратора', 'url' => ['/rbac/invite/index']], ['label' => 'Security Log', 'url' => ['/auth/security-log']], ], ], ], 'secondaryMenu' => [ [ 'icon' => 'palette', 'label' => 'ADMIN-UI-KIT', 'url' => ['/admin/site/ui-kit'], 'visible' => fn(): bool => !Yii::$app->user->isGuest, ], ], ], ],
Важно: ссылки
На сайт,Очистить кешиВыйтине нужно дублировать вsecondaryMenu. Они уже встроены в topbar-шапку layout справа.
Авторизация
В пакет уже встроен модуль авторизации:
- форма входа
- встроенное восстановление пароля для админки
- brute-force защита
- CAPTCHA после нескольких попыток
- lock по IP и email
- security log
- регистрация администратора по одноразовой ссылке
Маршруты:
GET/POST /admin/auth/loginGET/POST /admin/auth/request-password-resetGET/POST /admin/auth/reset-password?token=...GET/POST /admin/auth/invite?token=...POST /admin/auth/logoutGET /admin/auth/captchaGET /admin/auth/security-logPOST /admin/auth/clear-security-log
Внутри пакета используются короткие маршруты /auth/*, поэтому их нужно пробросить через urlManager.
Восстановление пароля
В странице входа уже встроена ссылка Забыли пароль?.
Сценарий работы:
- пользователь открывает
/admin/auth/request-password-reset - вводит email
- интерфейс всегда показывает одинаковое нейтральное success-состояние
- письмо реально отправляется только если пользователь существует, имеет доступ
adminPanel, модель поддерживает reset-token и в приложении настроенmailer
Это сделано специально, чтобы не раскрывать, какие email существуют в админке.
После успешной отправки форма скрывается, а на странице остается только сообщение и ссылка возврата ко входу.
Инвайт администратора
В пакет встроен сценарий регистрации нового администратора по одноразовой ссылке.
Сценарий работы:
- администратор открывает
/admin/rbac/invite - генерирует ссылку приглашения
- ссылка автоматически копируется в буфер обмена
- приглашенный пользователь открывает
/admin/auth/invite?token=... - проходит регистрацию
- после регистрации автоматически получает роль
adminи попадает в админку
Ограничения:
- генерация invite-ссылки доступна пользователям с ролью
admin - invite одноразовый
- системные ограничения для
ID=1относятся к защите root-администратора (рольadminне снимается), а не к генерации invite
Совместимость с моделью пользователя:
- если в проекте нет колонки
username, задайтеusernameField = 'email' - invite-регистрация автоматически подстроится и не будет выполнять SQL по
username - если
usernameесть как отдельное поле, форма invite продолжает работать в классическом режиме (логин + email + пароль)
RBAC
В пакет уже встроен RBAC-раздел:
- роли
- действия
- назначения ролей пользователям
- генерация одноразовых invite-ссылок для новых администраторов
Маршруты:
/admin/rbac/admin/rbac/user/admin/rbac/role/admin/rbac/permission/admin/rbac/assignment/admin/rbac/invite
Системные элементы
При установке RBAC автоматически создаются:
- роль
admin - действие
adminPanel - связь
admin -> adminPanel - назначение роли
adminпользователюID=1
Системные инварианты:
- пользователь с
ID=1является системным администратором и не может быть лишен ролиadmin - роль
adminявляется системной и не может быть удалена - действие
adminPanelявляется системным и не может быть удалено - связь
admin -> adminPanelдолжна существовать всегда - у пользователя с
ID=1рольadminдолжна сохраняться всегда - генерация invite-ссылок доступна пользователям с ролью
admin
Связь системных прав:
adminPanelсчитается системным permission для входа в админку- роль
adminдолжна включатьadminPanel - назначение только
adminPanelбез ролиadminможно использовать как технический допуск на уровень входа, но не как доступ к backend-разделам
Troubleshooting
Показывается дефолтная страница ошибки Yii вместо админской
Проверьте, что в конфиге приложения задано:
'errorHandler' => [ 'errorAction' => '/admin/site/error', ],
Также проверьте rule:
'admin/error' => 'admin/site/error',
Пропали стили в админке или отображается "голый" UI
Обычно это кеш опубликованных ассетов. Выполните:
- очистку
web/assets/* - очистку кеша приложения
Ctrl+F5в браузере
Циклический редирект на странице логина
Проверьте связку:
request.baseUrl = '/admin'user.loginUrl = ['/login']- правило
'login' => 'admin/auth/auth/login' - whitelist маршрутов входа/капчи/reset/invite в
beforeRequest-guard
403 на /admin/rbac/invite
Генерация инвайтов доступна роли admin. Проверьте, что у пользователя назначена роль admin в RBAC.
Общий контейнер страниц
В пакет встроен виджет:
larikmc\admin\widgets\AdminPage
Он нужен для единообразных внутренних страниц модулей. Его можно использовать и в собственных admin-разделах.
Пример:
echo \larikmc\admin\widgets\AdminPage::widget([ 'title' => 'Моя страница', 'subtitle' => 'Короткое описание раздела', 'actions' => [ \yii\bootstrap5\Html::a('Создать', ['create'], ['class' => 'btn btn-success']), ], 'content' => '<div>Контент страницы</div>', ]);
sz-panel
Базовый визуальный контейнер админки:
.sz-panel
Он задает:
- белый фон
- внутренние отступы
- скругление
- тень карточки
Используйте его для списков, форм, таблиц и detail-экранов, если нужен единый стиль панели.
Важно: не генерируйте для этого расширения лишнюю разметку (включая собственные breadcrumbs, дополнительные обертки под стили и отдельные UI-каркасы), если используете штатный layout админки. Виджет AdminPage, меню и базовые стили уже встроены и подключаются самим пакетом.
Пример ручного использования:
<div class="sz-panel">
<?= \yii\grid\GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => $columns,
]) ?>
</div>
Или для формы:
<div class="sz-panel">
<?= $this->render('_form', ['model' => $model]) ?>
</div>
Если страница строится через AdminPage, панель можно получить автоматически:
echo \larikmc\admin\widgets\AdminPage::widget([ 'title' => 'Список товаров', 'content' => \yii\grid\GridView::widget([...]), ]);
По умолчанию AdminPage оборачивает контент в .sz-panel.
Если панель нужна вручную в самом шаблоне, отключите автообертку:
echo \larikmc\admin\widgets\AdminPage::widget([ 'title' => 'Журнал безопасности', 'boxed' => false, 'content' => '<div class="sz-panel">...</div>', ]);
Плоский вариант без карточки:
.sz-panel--flat
Важно:
sz-panelэто базовый surface-контейнер для внутренних блоков админки- таблицы, формы, detail-view и типовые контентные секции должны жить внутри
sz-panel, если не нужен осознанно плоский вариант - для ручных alert-блоков не нужно возвращаться к bootstrap-default рамкам и фонам, если экран уже собирается из
sz-panelи toast-паттернов
Lazyload и popup для изображений
В расширение уже встроены:
- lazyload для изображений:
src/web/js/lazyloader.js - popup-просмотрщик оригинала:
src/web/js/image-viewer-admin.js - стили popup:
src/web/css/image-viewer-admin.css
Все эти файлы подключаются через larikmc\admin\assets\AppAsset, поэтому при штатном layout @larikmc/admin/views/layouts/main ничего отдельно регистрировать не нужно.
Стандартный placeholder для lazyload уже лежит в расширении:
src/web/img/load.svg
По умолчанию используется именно он. Если нужен свой placeholder, задайте его в конфиге модуля:
'modules' => [ 'admin' => [ 'class' => larikmc\admin\Module::class, 'lazyloadPlaceholderUrl' => '@web/img/load.svg', ], ],
В view URL placeholder лучше получать через модуль:
$placeholder = Yii::$app->getModule('admin')->getLazyloadPlaceholderUrl($this);
Базовый пример
Миниатюра грузится лениво из data-src, а по клику открывается оригинал из data-image-full:
use yii\bootstrap5\Html; $placeholder = Yii::$app->getModule('admin')->getLazyloadPlaceholderUrl($this); echo Html::a( Html::img($placeholder, [ 'data-src' => '/uploads/images/thumbs/item-123.webp', 'class' => 'sz-thumb__img', 'alt' => 'Изображение #123', 'loading' => 'lazy', 'decoding' => 'async', ]), '/uploads/images/original/item-123.jpg', [ 'data-pjax' => '0', 'data-image-viewer' => true, 'data-image-full' => '/uploads/images/original/item-123.jpg', 'data-image-title' => 'Изображение #123', 'class' => 'sz-thumb', 'style' => 'width:100px;height:72px;', ] );
Что здесь важно:
img[data-src]— URL миниатюры, которую нужно показать в таблице или спискеimg[src]— placeholder, по умолчанию стандартныйload.svgиз расширенияa[data-image-full]— URL полного изображения для popupa[href]— fallback для popup и обычная ссылка, если JS не загрузилсяa.sz-thumb— готовый контейнер, который центрирует placeholder и миниатюру, но не диктует размерimg.sz-thumb__img— картинка внутри контейнера, вписывается без растягиванияdata-pjax="0"— желательно для ссылок внутриGridView/PJAX, чтобы клик не перехватывался PJAX
Размер задаётся проектом:
['class' => 'sz-thumb', 'style' => 'width:100px;height:72px;']
Или готовым модификатором для типовых случаев:
sz-thumb sz-thumb--sm— 72x56sz-thumb sz-thumb--lg— 140x96sz-thumb sz-thumb--cover— изображение заполняет контейнер черезobject-fit: cover
Если миниатюра и оригинал совпадают
Можно не указывать data-image-full: popup возьмёт URL из href.
$placeholder = Yii::$app->getModule('admin')->getLazyloadPlaceholderUrl($this); echo Html::a( Html::img($placeholder, [ 'data-src' => '/uploads/images/item-123.jpg', 'class' => 'sz-thumb__img', 'alt' => 'Изображение #123', ]), '/uploads/images/item-123.jpg', [ 'data-pjax' => '0', 'data-image-viewer' => true, 'data-image-title' => 'Изображение #123', 'class' => 'sz-thumb', 'style' => 'width:100px;height:72px;', ] );
Пример для GridView
$placeholder = Yii::$app->getModule('admin')->getLazyloadPlaceholderUrl($this); [ 'attribute' => 'image', 'format' => 'raw', 'value' => static function ($model) use ($placeholder) { $thumb = '/uploads/images/items/thumbs/' . $model->image . '.webp'; $original = '/uploads/images/items/original/' . $model->image . '.jpg'; return \yii\bootstrap5\Html::a( \yii\bootstrap5\Html::img($placeholder, [ 'data-src' => $thumb, 'class' => 'sz-thumb__img', 'alt' => '', 'loading' => 'lazy', 'decoding' => 'async', ]), $original, [ 'data-pjax' => '0', 'data-image-viewer' => true, 'data-image-full' => $original, 'data-image-title' => 'Изображение #' . $model->id, 'class' => 'sz-thumb', 'style' => 'width:100px;height:72px;', ] ); }, ]
Legacy-вариант с onclick
Старый backend-паттерн тоже поддерживается:
$placeholder = Yii::$app->getModule('admin')->getLazyloadPlaceholderUrl($this); echo '<a class="sz-thumb" style="width:100px;height:72px;" data-pjax="0" data-image-viewer data-image-full="/uploads/images/original/item-123.jpg" data-image-title="Изображение #123" href="/uploads/images/original/item-123.jpg" onclick="return openAdminImageViewer(this)">' . '<img class="sz-thumb__img" src="' . $placeholder . '" data-src="/uploads/images/thumbs/item-123.webp" alt="">' . '</a>';
Новый вариант без inline onclick предпочтительнее: достаточно атрибута data-image-viewer.
Поддерживаемые атрибуты
data-srcнаimg— лениво подставляется вsrcdata-srcsetнаimg— лениво подставляется вsrcsetdata-no-placeholderнаimg— не добавлять классlazy-imgdata-image-viewerна ссылке — включает popup по кликуdata-image-fullна ссылке — оригинал для popupdata-image-titleна ссылке — подпись под изображениемtitleна ссылке — fallback для подписиhrefна ссылке — fallback для оригинала
Где должен лежать placeholder
Если вы ничего не настраиваете, placeholder берётся из расширения:
src/web/img/load.svg
После публикации Yii asset'ов он будет доступен по URL опубликованного AppAsset.
Если в конкретном проекте нужен другой spinner/placeholder, положите его в web-root проекта, например:
backend/web/img/load.svg
и укажите:
'lazyloadPlaceholderUrl' => '@web/img/load.svg',
Можно указать и абсолютный URL:
'lazyloadPlaceholderUrl' => 'https://cdn.example.com/admin/load.svg',
Обновление после AJAX/PJAX
При обычной загрузке страницы lazyload стартует сам. Если контент добавлен динамически, можно переинициализировать изображения внутри контейнера:
lazyloader.init(document.querySelector('#pjax-container'));
Если используется Yii PJAX:
document.addEventListener('pjax:end', function (event) { if (window.lazyloader) { window.lazyloader.init(event.target); } });
Popup использует делегирование клика на document, поэтому для новых ссылок с data-image-viewer повторная инициализация не нужна.
UI и grouped action-кнопки
В расширение уже встроены:
- общий layout админки
- базовые UI-стили
- переопределённые bootstrap-кнопки
.btn-* - стилизованные bootstrap-badges
.badge.text-bg-* - стили таблиц
- grouped action-кнопки в
GridView - showcase-страница
ADMIN-UI-KIT
Bootstrap-кнопки
Расширение не требует заводить отдельные "новые" классы для основных кнопок.
Вместо этого переопределяются стандартные bootstrap-классы:
.btn-primary.btn-secondary.btn-success.btn-danger.btn-warning.btn-info.btn-light.btn-outline-*
Это сделано специально, чтобы существующие view на Yii2 + Bootstrap 5 автоматически подхватывали новый стиль без массового переименования классов.
Bootstrap badges
Аналогично, для статусов и коротких меток используется стандартный bootstrap-формат:
.badge.text-bg-primary.text-bg-secondary.text-bg-success.text-bg-danger.text-bg-warning.text-bg-info.text-bg-light.text-bg-dark
То есть статусы и label-метки теперь лучше строить именно через bootstrap badges, а не через отдельные кастомные status-компоненты.
ADMIN-UI-KIT
Внутри пакета есть отдельная служебная страница:
/admin/site/ui-kit
Она нужна как showcase текущего визуального языка:
- solid buttons
- outline buttons
- badges
- metric card
- grouped action-column buttons
Удобно использовать её как reference, когда нужно повторить стиль в собственных backend-разделах.
То есть такие кнопки, как view/edit/delete, уже оформлены внутри пакета и не требуют ручного копирования CSS в проект, если используется штатный layout и asset bundle расширения.
Topbar и H1
В текущем layout заголовок страницы показывается в topbar автоматически через $this->title.
Это значит:
- topbar
H1приходит не изAdminPage, а из layoutsrc/views/layouts/main.php - параметр
showHeaderвAdminPageуправляет только внутренним заголовком внутри контента страницы showHeader => falseнужен как раз для того, чтобы не дублировать один и тот же заголовок и subtitle под topbar- для RBAC, security log и типовых CRUD-экранов
showHeader => falseявляется нормальным сценарием, еслиtitleуже выведен в topbar
Важно:
- в пакете нет рабочего параметра
showTopbarTitle - попытка "чинить" отсутствие заголовка через
$this->params['showTopbarTitle'] = trueявляется неправильной, потому что layout этот параметр не использует - если topbar
H1пропал, нужно проверятьlayout,$this->title, переопределённые view и фактическую версию пакета, а не размазывать по vendor-view несуществующий флаг
Важно понимать:
- если в другом проекте grouped-кнопки "не получились", это обычно не значит, что нужно просто вручную вставить CSS из README
- чаще причина в том, что не подключился asset bundle расширения (
AppAsset), либо кэш ассетов (web/assets/*) браузера не обновился.
Подробная техническая шпаргалка по этим кнопкам описана в разделе UI guide ниже.
UI guide
Этот раздел описывает текущий UI-слой админки larikmc/yii2-admin.
Где находится UI
- Layout:
src/views/layouts/main.php - Базовые стили:
src/web/css/style.css - Сайдбар:
src/web/css/dashboard.css - Главная dashboard-страница:
src/views/site/index.php - Стили dashboard-страницы:
src/web/css/home.css - JS для sidebar / dropdown / toast:
src/web/js/dashboard.js - Asset bundle:
src/assets/AppAsset.php
Как устроен текущий дизайн
- Основа интерфейса: светлый glass/panel стиль на cold blue/slate палитре.
- Сайдбар: тёмный, глубокий, с мягкой подсветкой и active-state у текущего пункта.
- Верхняя шапка: compact topbar с breadcrumbs и заголовком слева, utility-кнопками и аккаунтом справа.
- Карточки: крупные радиусы, мягкие границы, лёгкие градиенты, без тяжёлых bootstrap-рамок.
- Таблицы: стандартный Yii
GridView, но actions и часть UI переоформлены вручную.
Текущие UI-правила
- Не возвращать стандартные bootstrap alert'ы. Вместо них используются toast-уведомления справа сверху.
- Не дублировать один и тот же смысл в topbar и в контенте страницы.
- Для CRUD-страниц используется схема:
- topbar: breadcrumbs + title
- ниже отдельная actions-bar с кнопками
- ниже основной контент
- Для dashboard используется тот же compact topbar, что и для внутренних разделов.
- Кнопки действий в таблицах должны оставаться grouped, иконки в одной группе, без промежутков между сегментами.
- Аккаунт справа открывает dropdown только с logout-действием.
Быстрые действия в topbar
Справа в шапке сейчас есть:
- переход на сайт
- очистка кеша
- аккаунт с dropdown
Все три элемента должны выглядеть как единый набор: одинаковая высота, близкие радиусы, одна визуальная система.
Dashboard
Главная страница строится из двух зон:
- верхний hero-инфоблок
- сетка status-карточек
Текущее правило для hero:
- заголовок приветствия находится в topbar, а не внутри hero
- внутри hero остаётся только красиво оформленная системная информация
Таблицы GridView и блок Summary
Таблицы в Yii2 GridView оформлены в едином стиле UI-Kit:
- внешняя рамка со скруглением
14px(border: 1px solid var(--stroke)) находится на самой.grid-view .table; - поддерживается как светлая, так и тёмная тема (
#354660в dark mode); - разделители строк внутри таблицы и строки фильтров согласованы по цвету границы;
- у последней строки таблицы граница снизу обнулена (
border-bottom: 0), предотвращая сдвоенные толстые линии; - блок
summary(«Показаны записи 1-3 из 3») выводится аккуратным шрифтом12pxприглушенного цветаvar(--muted)без разделительных линий.
Табличные action-кнопки и пагинация (Автоматизировано)
В версии 2.1.3+ табличные действия и пагинация поддерживаются автоматически:
- Автоматическая стилизация дефолтного CRUD: стандартный вывод
yii\grid\ActionColumn(сгенерированный Gii или написанный вручную со стандартными SVG-иконкамиeye-open,pencil,trash) автоматически оформляется в монолитную аккуратную группу кнопок без необходимости ручной правки view и добавления классовsz-row-actionилиaction-column. - Delete-кнопка: кнопки с
data-method="post"илиdata-confirmавтоматически подсвечиваются danger-красным на hover в светлой и тёмной темах. - Кастомные кнопки: при ручном переопределении можно использовать иконки
Material Symbols Roundedи классsz-row-action. - Пагинация (LinkPager): стандартный
LinkPagerвGridViewавтоматически получает компактный скругленный вид UI kit (32x32px,8pxрадиус, primary подсветка активной страницы и корректный верхний отступ16px).
Что важно не сломать
appendTimestampиforceCopyуже включались в приложении, чтобы assets обновлялись корректно- layout и стили правятся в локальном пакете
d:\OpenServer6.5.0\home\yii2-admin, а не только в приложении - для CRUD-страниц часть view лежит уже в самом проекте
backend/views/... - для RBAC часть view лежит внутри пакета
src/rbac/views/...
Если нужно продолжать развитие UI
Предпочтительные направления:
- унифицировать все
GridViewфильтры и toolbar - держать одинаковую высоту topbar во всех разделах
- не добавлять лишний текст в hero и header
- сохранять холодную slate/blue палитру без слишком ярких кислотных акцентов
- новые элементы делать в том же стиле: мягкий border, glass-light background, крупный radius
Перед правками полезно проверить
src/views/layouts/main.phpsrc/web/css/style.csssrc/web/css/home.css- конкретную view проекта, если страница переопределена в
backend/views/...
После правок
- использовать жёсткое обновление страницы:
Ctrl+F5 - при сомнениях проверять опубликованные assets Yii
- для PHP view-файлов полезно гонять
php -l
Структура пакета
yii2-admin/
├─ src/
│ ├─ assets/
│ ├─ auth/
│ ├─ config/
│ ├─ controllers/
│ ├─ rbac/
│ ├─ views/
│ ├─ web/
│ ├─ widgets/
│ └─ Module.php
├─ composer.json
└─ README.md
Идея пакета
Это не набор из трех независимых расширений, а одна backend-платформа:
admin shellauthrbac
Именно поэтому пакет удобнее ставить и поддерживать как одно расширение.
Лицензия
BSD-3-Clause