Files
XC_VM/docs/ru/development/navbar-rendering.md
T
Divarion-D 76844fef11 docs: restructure, fix PSR-4 drift, and unify en/ru
Overhaul the Docsify documentation (English + Russian) so it matches the current
codebase and follows one consistent pattern.

Content accuracy (post-migration):
- Rewrite development/autoloader.md to PSR-4 / Composer (the old XC_Autoloader
  scanner, igbinary tmp/cache/autoload_map and registerDirectories are gone).
- PascalCase every source path (src/core -> src/Core, domain/Stream, cli/Commands,
  public/Controllers, Infrastructure/Redis, ...) across all docs.
- Replace the removed autoload.php references with vendor/autoload.php
  (build_system, bootstrap-contexts, error-handling, modules).
- ssl-generation: note that the installer now auto-generates a unique self-signed
  certificate before Nginx starts.

Common pattern (Clean & uniform):
- Strip emoji from headings; remove the in-page Navigation blocks (the Docsify
  sidebar already provides navigation).
- One H1 + intro per doc; uniform "Related files" / "Связанные файлы" section,
  added to the code-centric docs that lacked it.

Structure:
- Remove the empty stray docs/api/; move updates_checklist.md into builds/;
  link the previously-orphaned ucs-integration.md.
- Regroup the sidebars (split the oversized guides group into Developer Guides /
  Security & Access / Integrations; fold builds into Build & Release).

Augment:
- dev-workflow: Local Setup (make dev-tools) + Quality Checks (phpstan, cs, gates).
- build_system: Composer Dependencies section (committed prod-only vendor,
  committed lock, dev tools via composer install, no build-time vendor step).

en/ru parity:
- Apply the same structure, fixes and pattern to docs/ru/ (translated), including
  a new Russian ucs-integration.md. The en and ru file sets are now identical.
2026-06-26 15:56:15 +03:00

4.0 KiB
Raw Blame History

Рендер navbar в панели модулей

Техническая документация по формированию и рендерингу navbar в админ-панели.

Назначение

Navbar строится декларативно из дерева NavbarItem, а не из hardcoded HTML-меню.

Источник дерева:

  1. Core-узлы из CoreNavbarProvider::register().
  2. Модульные узлы из ModuleInterface::registerNavbar().

Жизненный цикл

  1. ModuleLoader::bootAll() вызывает CoreNavbarProvider::register().
  2. Затем для каждого загруженного модуля вызывается registerNavbar().
  3. В Public/Views/admin/header.php дерево рендерится из NavbarRegistry.

Рендер в header

Рендер выполняется helper-функциями:

  1. _xc_nav_visible() — фильтрация видимости узла.
  2. _xc_nav_label() — получение текстовой подписи.
  3. _xc_nav_children() — рекурсивный вывод дочерних пунктов.

Верхний уровень берётся через NavbarRegistry::getTopLevel(), дочерние узлы — через NavbarRegistry::getChildren($key).

Правила видимости

Проверки выполняются в _xc_nav_visible():

  1. desktopOnly: скрывает узел на мобильных.
  2. settingDisabled: скрывает узел при включённом settings-флаге.
  3. permissions: OR-проверка через Authorization::check('adv', $permission).
  4. Группа с url='#' показывается только если есть хотя бы один видимый потомок.
  5. divider всегда пропускается в рендер как разделитель.

Особенности рендера

  1. divider выводится как разделитель без ссылки.
  2. submenuClass('megamenu') включает двухколоночный вывод длинных списков.
  3. noMobileSubmenu выключает раскрытие дочернего меню на мобильных.

Как модулю добавить кнопку

Модуль добавляет пункты только через registerNavbar():

public function registerNavbar(): void {
    NavbarRegistry::add((new NavbarItem('management.service_setup.my_module'))
        ->parent('management.service_setup')
        ->url('my_module')
        ->label('my_module')
        ->permissions(['my_module'])
        ->order(60));

    NavbarRegistry::add((new NavbarItem('management.logs.my_module_log'))
        ->parent('management.logs')
        ->url('my_module_logs')
        ->label('', 'My Module Logs')
        ->permissions(['my_module'])
        ->order(170));
}

Практические правила для модулей

  1. Используйте уникальные key в формате section.group.item.
  2. Указывайте существующий parent из core-дерева или своего уже добавленного узла.
  3. Позиционируйте пункты через order внутри одного parent.
  4. Используйте label('translation_key') для переводимых строк.
  5. Используйте label('', 'Literal Text') для фиксированного текста.
  6. Если модуль не добавляет меню, оставляйте registerNavbar() пустым.

Связанные файлы

Файл Роль
src/Core/Module/NavbarRegistry.php Собирает пункты navbar от провайдеров
src/Core/Module/NavbarItem.php Value-объект пункта navbar
src/Core/Module/CoreNavbarProvider.php Встроенные пункты меню ядра
src/Public/Views/admin/header.php Рендерит дерево navbar