默认情况下,配置文件位于app/Providers/Filament/AdminPanelProvider.php。继续阅读以了解更多关于面板以及每个面板如何拥有其自己的配置文件。
默认情况下,当您安装此包时,会为您设置一个面板 - 它位于 /admin。您创建的所有 资源、自定义页面 和 仪表板小部件 都会注册到此面板。
然而,你可以创建任意数量的面板,并且每个都可以拥有自己的一套资源、页面和组件。
例如,你可以构建一个面板,在该面板中用户可以在 /app 登录并访问他们的仪表盘,而管理员可以在 /admin 登录并管理应用程序。/app 面板和 /admin 面板拥有各自的资源,因为每组用户都有不同的需求。Filament 允许你通过提供创建多个面板的能力来实现这一点。
当你运行 filament:install, 会创建一个新文件在 app/Providers/Filament - AdminPanelProvider.php. 此文件包含 /admin 面板的配置.
当本文档提到“配置”时,这就是你需要编辑的文件。它允许你完全自定义该应用。
要创建一个新面板,您可以使用 make:filament-panel 命令,并传入新面板的唯一名称:
php artisan make:filament-panel app此命令将创建一个名为 "app". 配置文件将创建在 app/Providers/Filament/AppPanelProvider.php. 你可以通过 /app, 但你可以 自定义路径 如果你不想那样.
由于此配置文件也是一个 Laravel 服务提供者,它需要注册到 bootstrap/providers.php (Laravel 11 及更高版本应用结构)或 config/app.php (Laravel 10 及更低版本应用结构)。Filament 会尝试为你完成此操作,但是如果你在尝试访问你的面板时遇到错误,那么此过程可能已失败。
在面板配置文件中,您可以使用 path() 方法更改应用程序可访问的路径:
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->path('app');
}如果你希望应用在没有任何前缀的情况下可访问,你可以将此设置为空字符串:
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->path('');
}确保您的 routes/web.php 文件尚未定义 '' 或 '/' 路由,因为它将优先。
渲染钩子允许你在框架视图的各个点渲染 Blade 内容。你可以注册全局渲染钩子在服务提供者或中间件中,但它也允许你注册特定于面板的渲染钩子。为此,你可以使用面板配置对象上的 renderHook() 方法。这是一个示例,它将 wire-elements/modal 与 Filament 集成:
use Filament\Panel;
use Filament\View\PanelsRenderHook;
use Illuminate\Support\Facades\Blade;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->renderHook(
PanelsRenderHook::BODY_START,
fn (): string => Blade::render('@livewire(\'livewire-ui-modal\')'),
);
}所有可用渲染钩子的完整列表可以在 此处 找到。
默认情况下,Filament 将响应来自所有域的请求。如果您想将其范围限定到特定域,您可以使用 domain() 方法,类似于 Laravel 中的 Route::domain():
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->domain('admin.example.com');
}默认情况下,Filament 会限制页面内容的宽度,以免在大屏幕上内容过宽。要更改此设置,您可以使用 maxContentWidth() 方法。选项对应于 Tailwind 的最大宽度比例。选项包括 ExtraSmall, Small, Medium, Large, ExtraLarge, TwoExtraLarge, ThreeExtraLarge, FourExtraLarge, FiveExtraLarge, SixExtraLarge, SevenExtraLarge, Full, MinContent, MaxContent, FitContent, Prose, ScreenSmall, ScreenMedium, ScreenLarge, ScreenExtraLarge 和 ScreenTwoExtraLarge。默认值为 SevenExtraLarge:
use Filament\Panel;
use Filament\Support\Enums\Width;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->maxContentWidth(Width::Full);
}如果您想设置类型为SimplePage的页面的最大内容宽度,例如登录和注册页面,您可以使用simplePageMaxContentWidth()方法。默认值为Large:
use Filament\Panel;
use Filament\Support\Enums\Width;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->simplePageMaxContentWidth(Width::Small);
}子导航默认在每个页面的开头渲染。它可以按页面、按资源和按集群进行自定义,但您也可以使用 subNavigationPosition() 方法一次性为整个面板自定义它。该值可以是 SubNavigationPosition::Start、SubNavigationPosition::End 或 SubNavigationPosition::Top,以将子导航渲染为选项卡:
use Filament\Pages\Enums\SubNavigationPosition;
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->subNavigationPosition(SubNavigationPosition::End);
}钩子可用于在面板的生命周期中执行代码。bootUsing() 是一个钩子,在面板内发生的每个请求上运行。如果您有多个面板,则只会运行当前面板的 bootUsing()。该函数在所有服务提供者启动后,从中间件运行:
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->bootUsing(function (Panel $panel) {
// ...
});
}SPA 模式利用 Livewire 的 wire:navigate 功能 使您的服务器渲染面板感觉像单页应用一样,页面加载延迟更短,并且在长时间请求时显示加载条。要在面板上启用 SPA 模式,您可以使用 spa() 方法:
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->spa();
}默认情况下,当启用 SPA 模式时,与当前请求位于同一域的任何 URL 都将使用 Livewire 的 wire:navigate 功能进行导航。如果您想为特定 URL 禁用此功能,可以使用 spaUrlExceptions() 方法:
use App\Filament\Resources\Posts\PostResource;
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->spa()
->spaUrlExceptions(fn (): array => [
url('/admin'),
PostResource::getUrl(),
]);
}在此示例中,我们正在使用 getUrl() 在资源上获取该资源的索引页面的 URL。此功能要求面板已经注册,但配置在请求生命周期中过早,无法完成此操作。你可以使用一个函数来代替返回 URL,该函数将在面板注册后得到解析。
这些 URL 需要精确匹配用户正在导航到的 URL,包括域名和协议。如果您想使用模式来匹配多个 URL,您可以使用星号 (*) 作为通配符:
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->spa()
->spaUrlExceptions([
'*/admin/posts/*',
]);
}SPA 预取通过在用户悬停在链接上时自动预取页面,从而提升用户体验,使导航感觉更加响应迅速。此功能利用 Livewire 的 wire:navigate.hover 功能。
要启用带预取功能的 SPA 模式,您可以将 hasPrefetching: true 参数传递给 spa() 方法:
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->spa(hasPrefetching: true);
}当预取启用时,面板内的所有链接将自动包含wire:navigate.hover,当用户将鼠标悬停在链接上时,它会预取页面内容。这与URL 异常无缝协作 - 任何从 SPA 模式中排除的 URL 也将从预取中排除。
预取仅在 SPA 模式启用时有效。如果禁用 SPA 模式,预取也将自动禁用。
预加载大型页面可能导致带宽使用量和服务器负载增加,尤其是在用户快速连续地将鼠标悬停在许多链接上时。请谨慎使用此功能,尤其是在您的应用包含大量数据或复杂查询的页面时。
您可以提醒用户,如果他们尝试在未保存更改的情况下离开页面。这适用于资源的[创建](resources/creating-records)和[编辑](resources/editing-records)页面,以及任何已打开的操作模态框。要启用此功能,您可以使用unsavedChangesAlerts()方法:
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->unsavedChangesAlerts();
}默认情况下,Filament 不会将操作包装在数据库事务中,并允许用户在他们测试确认其操作可以安全地包装在事务中后自行启用此功能。但是,您可以通过使用 databaseTransactions() 方法,一次性为所有操作启用数据库事务:
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->databaseTransactions();
}对于任何你不想封装在事务中的操作,你可以使用 databaseTransaction(false) 方法:
CreateAction::make()
->databaseTransaction(false)对于任何类似 创建资源 和 编辑资源 的页面,你可以在页面类中将 $hasDatabaseTransactions 属性定义为 false:
use Filament\Resources\Pages\CreateRecord;
class CreatePost extends CreateRecord
{
protected ?bool $hasDatabaseTransactions = false;
// ...
}与其在所有地方启用数据库事务并为特定操作和页面选择退出它们,不如你可以为特定操作和页面选择加入数据库事务。
对于操作,您可以使用 databaseTransaction() 方法:
CreateAction::make()
->databaseTransaction()对于像 创建资源 和 编辑资源 这样的页面,您可以在页面类上将 $hasDatabaseTransactions 属性定义为 true:
use Filament\Resources\Pages\CreateRecord;
class CreatePost extends CreateRecord
{
protected ?bool $hasDatabaseTransactions = true;
// ...
}你可以注册 资产 仅在特定面板内的页面上加载,而不会在应用程序的其余部分加载。为此,将一个资产数组传递给 assets() 方法:
use Filament\Panel;
use Filament\Support\Assets\Css;
use Filament\Support\Assets\Js;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->assets([
Css::make('custom-stylesheet', resource_path('css/custom.css')),
Js::make('custom-script', resource_path('js/custom.js')),
]);
}在这些 资源 可以使用之前,你需要运行 php artisan filament:assets。
您可以通过在配置中将一个中间件类数组传递给 middleware() 方法,从而将额外的中间件应用于所有路由:
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->middleware([
// ...
]);
}默认情况下,中间件会在页面首次加载时运行,但不会在后续的 Livewire AJAX 请求中运行。如果你想在每个请求上运行中间件,可以通过将 true 作为 middleware() 方法的第二个参数传递来使其持久化:
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->middleware([
// ...
], isPersistent: true);
}你可以通过在配置中将一个中间件类数组传递给 authMiddleware() 方法,从而将中间件应用于所有已认证的路由:
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->authMiddleware([
// ...
]);
}默认情况下,中间件会在页面首次加载时运行,但不会在后续的 Livewire AJAX 请求中运行。如果你想让中间件在每次请求时都运行,可以通过将 true 作为第二个参数传入 authMiddleware() 方法来使其持久化:
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->authMiddleware([
// ...
], isPersistent: true);
}默认情况下,Laravel Echo 将为每个面板自动连接,如果已在 已发布的 config/filament.php 配置文件 中设置了凭据。要禁用面板中的此自动连接,您可以使用 broadcasting(false) 方法:
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->broadcasting(false);
}默认情况下,当 Filament 授权用户访问资源时,它会首先检查该模型是否存在策略,如果存在,它会检查该策略上是否存在用于执行操作的方法。如果策略或策略方法不存在,它将授予用户访问资源的权限,因为它假定您尚未设置授权,或者您不需要它。
如果您希望 Filament 在策略或策略方法不存在时抛出异常,您可以使用 strictAuthorization() 方法启用严格授权模式:
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->strictAuthorization();
}当 Laravel 的调试模式被禁用时,Filament 将会用更整洁的快闪通知替换 Livewire 的全屏错误模态框。你可以使用 errorNotifications(false) 方法禁用此行为:
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->errorNotifications(false);
}您可以通过将字符串传递给 registerErrorNotification() 方法的 title 和 body 参数来定制错误通知文本:
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->registerErrorNotification(
title: 'An error occurred',
body: 'Please try again later.',
);
}您也可以注册错误通知文本用于特定的 HTTP 状态码,例如 404,通过在 statusCode 参数中传入该状态码:
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->registerErrorNotification(
title: 'An error occurred',
body: 'Please try again later.',
)
->registerErrorNotification(
title: 'Record not found',
body: 'A record you are looking for does not exist.',
statusCode: 404,
);
}你还可以通过在页面类上设置 $hasErrorNotifications 属性,来启用或禁用面板中特定页面的错误通知:
use Filament\Pages\Dashboard as BaseDashboard;
class Dashboard extends BaseDashboard
{
protected ?bool $hasErrorNotifications = true;
// or
protected ?bool $hasErrorNotifications = false;
// ...
}如果您想运行自定义代码来检查是否应显示错误通知,您可以使用页面类上的 hasErrorNotifications() 方法:
use Filament\Pages\Dashboard as BaseDashboard;
class Dashboard extends BaseDashboard
{
public function hasErrorNotifications(): bool
{
return FeatureFlag::active();
}
// ...
}您也可以通过从 setUpErrorNotifications() 方法内部调用页面类上的 registerErrorNotification() 方法来注册错误通知文本:
use Filament\Pages\Dashboard as BaseDashboard;
class Dashboard extends BaseDashboard
{
protected function setUpErrorNotifications(): void
{
$this->registerErrorNotification(
title: 'An error occurred',
body: 'Please try again later.',
);
}
// ...
}您还可以为特定的 HTTP 状态码注册错误通知文本,例如 404,通过在 statusCode 参数中传递该状态码:
use Filament\Pages\Dashboard as BaseDashboard;
class Dashboard extends BaseDashboard
{
protected function setUpErrorNotifications(): void
{
$this->registerErrorNotification(
title: 'An error occurred',
body: 'Please try again later.',
);
$this->registerErrorNotification(
title: 'Record not found',
body: 'A record you are looking for does not exist.',
statusCode: 404,
);
}
// ...
}