- Объект Navigation
- Добавление разделов
- Добавление разделов в виде массива
- Добавление секции в подраздел при инициализации
- Получение списка разделов
- Получение кол-ва разделов с учетом вложенности
- Права на видимость разделов
- Пример меню
- Объект раздела
- Badges
- Page Collection
Конфигурация меню SleepingOwl Admin по умолчанию располагается в app/Admin/navigation.php
. Если файл
возвращает массив, то этот массив будет также использоваться для построения меню.
Navigation представлен классом SleepingOwl\Admin\Navigation
(Реализует интерфейс KodiComponents\Navigation\Contracts\NavigationInterface
), который инициализируется через Service Container - sleeping_owl.navigation
и доступен с помощью:
$navigation = app('sleeping_owl.navigation');
AdminNavigation
Данный объект содержит в себе массив всех элементов меню для административного интерфейса.
В меню можно добавлять любые объекты реализующие интерфейс KodiComponents\Navigation\Contracts\PageInterface
addPage(string|array|PageInterface $page): PageInterface
Если в качестве аргумента передана строка или массив, то в качестве раздела будет создан объект SleepingOwl\Admin\Navigation\Page
При передаче параметров раздела в виде массива, будет произведен обход каждого ключа массива и вызван метод set + $key
и передано в качестве аргумента значение, т.е.
AdminNavigation::addPage(['title' => 'test', 'priority' => 100, 'bage' => function() {
return 100
}]);
// выполнит следующее
$page = app()->make(KodiComponents\Navigation\Contracts\PageInterface::class);
$page->setTitle('test');
$page->setPriority(100);
$page->addBadge(function() { // Для бейджев несколько другое условие
return 100
});
$navigation->getPages()->push($page);
При передаче параметра раздела в виде строки, будет создан новый объект раздела и указан заголовок.
AdminNavigation::addPage('test');
// выполнит следующее
$page = app()->make(KodiComponents\Navigation\Contracts\PageInterface::class);
$page->setTitle('test');
$navigation->getPages()->push($page);
В навигацию будет добавлен новый раздел - переданный объект
AdminNavigation::addPage(Page $page);
$navigation->getPages()->push($page);
Новый раздел в меню можно добавить несколькими способами:
app('sleeping_owl.navigation')
->addPage()
->setTitle('Blog')
->setUrl('/blog');
// Создание элемента меню для модели
AdminNavigation::addPage('Blog')
->setPriority(100)
->setIcon('fa fa-newspaper-o');
AdminSection::addMenuPage(\App\User::class);
Для более удобной генерации меню можно передавать список разделов в виде массива, тогда при обходе массива меню, для каждого раздела будет вызван метод addPage
Пример
AdminNavigation::setFromArray([
[
'title' => 'Permissions',
'icon' => 'fa fa-group',
'pages' => [
[
'title' => 'Users',
'url' => ...
],
[
'title' => 'Roles',
'url' => ...
],
]
],
(new \SleepingOwl\Admin\Navigation\Page(\App\Model\News::class))
->setIcon('fa fa-newspaper-o')
->setPriority(0)
]);
Данные правила действуют и для внутренних разделов
$page = new \SleepingOwl\Admin\Navigation\Page(\App\Model\News::class);
$page->setIcon('fa fa-newspaper-o');
$page->setFromArray([
...
]);
Внимание: Что бы добавление работало, необходимо, чтобы инициализация классов разделов, происходила раньше, чем обработка секций.
// AdminSectionsServiceProvider.php
public function boot(\SleepingOwl\Admin\Admin $admin)
{
...
$this->app->call([$this, 'registerNavigation']);
parent::boot($admin);
...
}
Если вы хотите добавить секцию, как подраздел пункта меню, в ходе инициализации секции, то необходимо установить id этого пункта меню для последующего поиска:
[
'title' => 'Parent Section',
'id' => 'parent-section'
],
Далее в секции производим поиск родительского раздела и добавляем свою секцию:
/**
* Initialize class.
*/
public function initialize()
{
$page = \AdminNavigation::getPages()->findById('parent-section');
$page->addPage(
$this->makePage(300)
);
}
AdminNavigation::getPages(): KodiComponents\Navigation\PageCollection
$page = AdminNavigation::getPages()->first(): KodiComponents\Navigation\Contracts\PageInterface
$page->getPages(): KodiComponents\Navigation\PageCollection
AdminNavigation::countPages(): int;
AdminNavigation::getPages()->first()->countPages(); // Подсчет кол-во детей для конкретного раздела
Также для разделов меню можно настраивать правила видимости. Процесс проверки прав доступа выглядит следующим образом: каждый объект меню может иметь свое локальное правило проверки прав
AdminNavigation::addPage(\App\Blog::class)->setAccessLogic(function() {
return auth()->user()->isSuperAdmin();
})
Если правило для страницы не указано:
- Если пункт меню является ссылкой на раздел и раздел не доступен для просмотра, пункт исчезнет из меню
- Если у страницы есть предок, то происходит проверка наличия правила, если оно указано, то будет произведена проверка
- если предок не имеет правила, то подъем дальше по иерархии до глобального правила.
Есть несколько сценариев настройки прав доступа:
- Указать глобальное правило
AdminNavigation::setAccessLogic(function(Page $page) {
return auth()->user()->isSuperAdmin();
});
- Указать правило для конкретной страницы
- Указать правило для раздела содержащего страницы, это правило распространится на все внутренние страницы не имеющие своего правила
Вот простой пример как может выглядеть конфигурация меню:
return [
[
'title' => 'Permissions',
'icon' => 'fa fa-group',
'pages' => [
(new Page(\App\User::class))
->setIcon('fa fa-user')
->setPriority(0),
(new Page(\App\Role::class))
->setIcon('fa fa-group')
->setPriority(100)
]
]
];
Каждый раздел меню (страница) - объект SleepingOwl\Admin\Navigation\Page
, реализующий
интерфейс KodiComponents\Navigation\Contracts\PageInterface
и наследует
интерфейс KodiComponents\Navigation\Contracts\NavigationInterface
, т.е. каждый раздел ведет себя также как и объект Navigation
Данный объект содержит все параметры текущей страницы, а также массив вложенных разделов.
На данный момент доступны два класса страниц
KodiComponents\Navigation\Page
- для создания обычных разделовSleepingOwl\Admin\Navigation\Page
- для создания разделов привязанных к классу конфигурации модели
new KodiComponents\Navigation\Page(
string $title = null,
string|Illuminate\Contracts\Routing\UrlGenerator $url = null,
string $id = null,
int $priority = 100,
string $icon = null
)
new SleepingOwl\Admin\Navigation\Page(
string $modelClass = null
)
Добавление дополнительного списка url
адресов, по которым данный раздел должен быть активен
Добавление дочерних страниц через анонимную функцию
$page->setPages(function($page) {
$page->addPage(...);
});
Добавление уникального идентификатора для страницы, необходим для поиска страницы
AdminNavigation::addPage(['title' => '...', 'id' => 'unique_string']);
Указание заголовка для страницы
Указание иконки для страницы
Указание ссылки
Указание приоритета вывода
Получение массива заголовков для текущего раздела с учетом родительских разделов
$page1 = 'Title 1';
$page2 = 'Title 2';
$page3 = 'Title 3';
$page3->getPath() // ['Title 1', 'Title 2', 'Title 3']
Получение массива (цепочки) от текущей страницы для корневой для построения хлебных крошек
Каждая страница может содержать неограниченное кол-во бейджев. При вызове метода setBadge
или addBadge
происходит передача текущего бейджа в стек. При выводе страницы будут выведены все бейджы из стека.
Добавление объекта бейджа
Добавление бейджа
$page->addBadge(function() {
return News::count();
}, ['class' => 'label-danger'])
Объект KodiComponents\Navigation\PageCollection
наследуется от Illuminate\Support\Collection
и содержит массив
дочерних страниц для разделов и объекта навигации.
Поиск станицы по ID
AdminNavigation::getPages()->findById('unique_string'): PageInterface|null
Поиск станицы по пути вложенности
// с разделителем `Title 1/Title 2/Title 3`
AdminNavigation::getPages()->findByPath('Title 1/Title 2/Title 3'): PageInterface|null