默认情况下,Nova 的左侧主导航菜单会显示应用程序的所有仪表盘、资源以及您注册的任何自定义工具。
在渲染主菜单时,Nova 会根据应用程序的 App\Providers\NovaServiceProvider
类中 dashboards
方法返回的顺序对仪表盘进行排序。
Nova 还会根据 Resource
类中定义的 group
属性,将您的资源自动分组到默认的“资源”菜单部分。此外,您注册的任何自定义工具都将按您在应用程序的 NovaServiceProvider
中定义的顺序列出。
虽然 Nova 的默认主菜单足以满足大多数应用程序的需求,但有时您可能希望根据自己的偏好完全自定义菜单。为此,Nova 允许您通过 Nova::mainMenu
方法定义自己的主菜单。通常,此方法应在应用程序的 App\Providers\NovaServiceProvider
类的 boot
方法中调用。
<?php
namespace App\Providers;
use App\Nova\License;
use App\Nova\Release;
use App\Nova\Series;
use App\Nova\User;
use Illuminate\Http\Request;
use Laravel\Nova\Dashboards\Main;
use Laravel\Nova\Menu\Menu;
use Laravel\Nova\Menu\MenuItem;
use Laravel\Nova\Menu\MenuSection;
use Laravel\Nova\Nova;
use Laravel\Nova\NovaApplicationServiceProvider;
class NovaServiceProvider extends NovaApplicationServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
parent::boot();
Nova::mainMenu(function (Request $request) {
return [
MenuSection::dashboard(Main::class)->icon('chart-bar'),
MenuSection::make('Customers', [
MenuItem::resource(User::class),
MenuItem::resource(License::class),
])->icon('user')->collapsable(),
MenuSection::make('Content', [
MenuItem::resource(Series::class),
MenuItem::resource(Release::class),
])->icon('document-text')->collapsable(),
];
});
}
}
Nova 还允许您自定义位于右上角导航区域的“用户”菜单。您可以通过调用 Nova::userMenu
方法来自定义 Nova 的用户菜单。此方法通常在应用程序的 App\Providers\NovaServiceProvider
的 boot
方法中调用。
<?php
namespace App\Providers;
use Illuminate\Http\Request;
use Laravel\Nova\Menu\Menu;
use Laravel\Nova\Menu\MenuItem;
use Laravel\Nova\Nova;
use Laravel\Nova\NovaApplicationServiceProvider;
class NovaServiceProvider extends NovaApplicationServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Nova::userMenu(function (Request $request, Menu $menu) {
if ($request->user()->subscribed()) {
$menu->append(
MenuItem::make('Subscriber Dashboard')
->path('/subscribers/dashboard')
);
}
$menu->prepend(
MenuItem::make(
'My Profile',
"/resources/users/{$request->user()->getKey()}"
)
);
return $menu;
});
}
}
用户菜单注销链接
默认情况下,Nova 配置为在用户菜单中显示“注销”链接。此链接不可删除。
用户菜单项
Nova 的用户菜单仅支持 MenuItem
对象。在用户菜单中使用 MenuSection
或 MenuGroup
将会抛出 Exception
。
您可以调用Menu
实例上的append
和prepend
方法,在菜单中添加或插入新项。这些方法通常在自定义用户菜单时最有用,因为您通常不希望完全替换现有菜单。
Nova::userMenu(function (Request $request, Menu $menu) {
return $menu
->append(MenuItem::externalLink('API Docs', 'http://example.com'))
->prepend(MenuItem::link('My Profile', '/resources/users/'.$request->user()->getKey()));
});
菜单部分代表顶级导航项,通常会显示一个相应的图标,代表菜单中项目的类型。您可以通过调用MenuSection::make
方法创建一个新的菜单部分。此方法接受菜单部分的名称和应放置在部分内的菜单组/项目的数组。
use App\Nova\Dashboards\Sales;
use App\Nova\Lenses\MostValuableUsers;
use App\Nova\License;
use App\Nova\Refund;
use App\Nova\User;
use Illuminate\Http\Request;
use Laravel\Nova\Menu\Menu;
use Laravel\Nova\Menu\MenuGroup;
use Laravel\Nova\Menu\MenuItem;
use Laravel\Nova\Menu\MenuSection;
use Laravel\Nova\Nova;
Nova::mainMenu(function (Request $request, Menu $menu) {
return [
MenuSection::make('Business', [
MenuGroup::make('Licensing', [
MenuItem::dashboard(Sales::class),
MenuItem::resource(License::class),
MenuItem::resource(Refund::class),
MenuItem::externalLink('Stripe Payments', 'https://dashboard.stripe.com/payments?status%5B%5D=successful'),
]),
MenuGroup::make('Customers', [
MenuItem::lens(User::class, MostValuableUsers::class),
]),
]),
];
});
除了显示链接列表,您还可以指示菜单部分只是一个指向其他位置的大型强调链接。为此,您可以在定义菜单部分时调用path
方法。
use Laravel\Nova\Menu\MenuSection;
MenuSection::make('Dashboard')->path('/dashboards/main')
为了方便起见,如果您只是创建一个菜单部分作为指向 Nova 仪表盘的大型强调链接,您可以调用MenuSection::dashboard
方法。
use App\Nova\Dashboards\Sales;
use Laravel\Nova\Menu\MenuSection;
MenuSection::dashboard(Sales::class),
由于您经常会创建指向 Nova 资源的链接,您可以使用resource
方法快速创建指向给定资源的适当路径的链接。
use App\Nova\User;
use Laravel\Nova\Menu\MenuSection;
MenuSection::resource(User::class)
同样,您可以通过lens
方法创建指向 Nova 透镜的链接。
use App\Nova\Lenses\MostValuableUsers;
use App\Nova\User;
use Laravel\Nova\Menu\MenuSection;
MenuSection::lens(User::class, MostValuableUsers::class)
菜单部分作为链接
定义为collapsable
的菜单部分不支持也作为链接。在菜单部分为collapseable
时调用path
将导致不显示任何链接。
您可以在定义菜单部分时调用icon
方法,自定义为菜单部分显示的图标。
use Laravel\Nova\Menu\MenuSection;
MenuSection::make('Resources', [
// items
])->icon('briefcase')
Nova 使用由Steve Schoger提供的免费Heroicons图标集。因此,您只需在向icon
方法提供图标名称时指定其中一个图标的名称。
您可以通过在MenuSection
上调用withBadge
方法并指定徽章的选项,为菜单部分添加视觉徽章。
use App\Models\Issue;
use Laravel\Nova\Menu\MenuSection;
use Laravel\Nova\Badge;
// Passing a string directly
MenuSection::make('New Issues')
->path('/resources/issues/lens/new-issues')
->withBadge('New!', 'success')
->icon('document-text')
// Passing a Laravel\Nova\Badge instance directly
MenuSection::make('New Issues')
->path('/resources/issues/lens/new-issues')
->withBadge(Badge::make('New!', 'info'))
->icon('document-text')
// Using a closure to resolve the value
MenuSection::make('New Issues')
->path('/resources/issues/lens/new-issues')
->withBadge(fn () => Issue::count(), 'warning')
->icon('document-text')
使用 withBadgeIf
方法,您可以有条件地添加徽章,仅当满足给定条件时才添加。
use App\Models\Issue;
use Laravel\Nova\Menu\MenuSection;
use Laravel\Nova\Badge;
// Passing a string directly...
MenuSection::make('New Issues')
->path('/resources/issues/lens/new-issues')
->withBadgeIf('New!', 'info', fn () => Issue::count() > 0)
// Passing a Laravel\Nova\Badge instance...
MenuSection::make('New Issues')
->path('/resources/issues/lens/new-issues')
->withBadgeIf(Badge::make('New!', 'info'), fn () => Issue::count() > 0)
// Using a closure to resolve the value...
MenuSection::make('New Issues')
->path('/resources/issues/lens/new-issues')
->withBadgeIf(fn() => 'New!', 'info', fn () => Issue::count() > 0)
您可以在定义菜单部分时调用 collapsable
方法,使您的菜单部分可折叠。为了方便起见,Nova 会在请求之间记住该部分的打开状态。
use Laravel\Nova\Menu\MenuSection;
MenuSection::make('Resources', [
//
])->collapsable()
有时您可能需要在菜单部分和菜单项之间添加另一个逻辑级别。在这种情况下,菜单组是完美的解决方案。菜单组允许您将菜单项分组到它们自己的强调标题下。
use App\Nova\Dashboards\Sales;
use App\Nova\License;
use App\Nova\Refund;
use Illuminate\Http\Request;
use Laravel\Nova\Menu\MenuGroup;
use Laravel\Nova\Menu\MenuItem;
use Laravel\Nova\Menu\MenuSection;
MenuSection::make('Business', [
MenuGroup::make('Licensing', [
MenuItem::dashboard(Sales::class),
MenuItem::resource(License::class),
MenuItem::resource(License::class),
MenuItem::externalLink('Stripe Payments', 'https://dashboard.stripe.com/payments?status%5B%5D=successful'),
]),
]),
您可以在组上调用 collapsable
方法,使您的菜单组可折叠。为了方便起见,Nova 会在请求之间记住该组的打开状态。
MenuGroup::make('Resources', [
//
])->collapsable()
菜单项代表不同类型的链接,这些链接指向应用程序内部和外部的区域,可以添加到自定义 Nova 菜单中。Nova 附带了一些方便的方法,用于创建不同类型的菜单项。
首先,要创建指向 Nova 内部区域的链接,您可以在 MenuItem
类上调用 link
工厂方法。
use Laravel\Nova\Menu\MenuItem;
MenuItem::link('Cashier', '/cashier')
由于您经常会创建指向 Nova 资源的链接,您可以使用resource
方法快速创建指向给定资源的适当路径的链接。
use App\Nova\User;
use Laravel\Nova\Menu\MenuItem;
MenuItem::resource(User::class)
要创建指向具有预定义过滤器应用的 Nova 资源的链接,您可以使用 filter
方法,传入过滤器实例及其应接收的值。由于过滤器可以与多个资源一起使用,因此您还必须为菜单项传递一个名称,因为它无法自动生成。
use App\Nova\User;
use Laravel\Nova\Menu\MenuItem;
use \App\Nova\Filters\NameFilter;
MenuItem::filter('Filtered Users', User::class, NameFilter::make(), 'Hemp');
您还可以将多个过滤器传递给资源菜单项。例如,假设您想创建一个链接到 User
资源的菜单项,显示电子邮件以 @laravel.com
结尾且状态为 active
的用户。
use App\Nova\User;
use Laravel\Nova\Menu\MenuItem;
use \App\Nova\Filters\EmailFilter;
use \App\Nova\Filters\StatusFilter;
MenuItem::filter('Filtered Users', User::class)
->applies(EmailFilter::make(), '@laravel.com')
->applies(StatusFilter::make(), 'active');
Nova 过滤器也可以接收构造函数参数,以便在资源之间方便地重复使用您的过滤器。要创建过滤后的资源菜单项时传递参数,只需将它们提供给过滤器的 make
方法。
use App\Nova\User;
use Laravel\Nova\Menu\MenuItem;
use App\Nova\Filters\ColumnFilter;
MenuItem::filter('Active Laravel Users', User::class)
->applies(ColumnFilter::make('name'), 'Hemp');
与资源项类似,您可以通过 lens
方法创建指向 Nova 透镜的链接。
use App\Nova\Lenses\MostValuableUsers;
use App\Nova\User;
use Laravel\Nova\Menu\MenuItem;
MenuItem::lens(User::class, MostValuableUsers::class)
您还可以通过调用 dashboard
工厂方法创建指向任何 自定义 Nova 仪表板 的链接。
use App\Nova\Dashboards\Main;
use Laravel\Nova\Menu\MenuItem;
MenuItem::dashboard(Main::class)
要创建将用户引导到 Nova 应用程序之外的某个位置的链接,您可以使用 externalLink
工厂方法。
use Laravel\Nova\Menu\MenuItem;
MenuItem::externalLink('Documentation', 'https://nova.laravel.net.cn/docs')
要指定外部链接应在单独的选项卡中打开,您可以在菜单项上调用 openInNewTab
方法。
MenuItem::externalLink('Documentation', 'https://nova.laravel.net.cn/docs')->openInNewTab();
您还可以调用 method
帮助程序来传入 HTTP 方法、请求数据以及单击链接时应发送到应用程序的任何 HTTP 标头。这通常对像注销链接这样的项目很有用,这些项目应该是 POST
请求。
use Laravel\Nova\Menu\MenuItem;
MenuItem::externalLink('Logout', 'https://api.yoursite.com/logout')
->method(
'POST',
data: ['user' => 'hemp'],
headers: ['API_TOKEN' => 'abcdefg1234567']
)
您可以通过在 MenuItem
上调用 withBadge
方法并指定徽章的选项来向菜单项添加视觉徽章。
use App\Nova\Dashboards\Issue;
use Laravel\Nova\Menu\MenuItem;
use Laravel\Nova\Badge;
// Passing a string directly
MenuItem::dashboard(Issue::class)
->withBadge('New!', 'info')
// Passing a Laravel\Nova\Badge instance directly
MenuItem::dashboard(Issue::class)
->withBadge(Badge::make('New!', 'info'))
// Using a closure to resolve the value
MenuItem::dashboard(Issue::class)
->withBadge(fn() => 13, 'danger')
您也可以仅在满足条件时才添加徽章。
use App\Nova\Issue;
use Laravel\Nova\Menu\MenuItem;
// Passing a string directly
MenuItem::resource(Issue::class)
->withBadgeIf('New!', 'info', fn() => Issue::newModel()->count() > 0)
// Passing a Laravel\Nova\Badge instance directly
MenuItem::resource(Issue::class)
->withBadgeIf(Badge::make('New!', 'info'), fn() => Issue::newModel()->count() > 0)
// Using a closure to resolve the value
MenuItem::resource(Issue::class)
->withBadgeIf(fn() => 'New!', 'info', fn() => Issue::newModel()->count() > 0)
您可以使用 canSee
方法来确定是否应为当前经过身份验证的用户显示菜单项。
MenuItem::link('Cashier', '/cashier')
->canSee(function (NovaRequest $request) {
return $request->user()->can('manageCashier');
})