跳到主要内容
版本:3.0

开始

概述

资源是用来为 Eloquent 模型创建 CRUD 接口的静态类。它描述了管理员如何在应用内,使用表格和表单,与数据进行交互的。

新建资源

App\Models\Customer 模型新建资源:

php artisan make:filament-resource Customer

app/Filament/Resources 目录下将会生成一系列文件:

.
+-- CustomerResource.php
+-- CustomerResource
| +-- Pages
| | +-- CreateCustomer.php
| | +-- EditCustomer.php
| | +-- ListCustomers.php

新的资源类在 CustomerResource.php 中。

Pages 目录下的类用于自定义应用中和资源交互的页面。这些页面是全页 Livewire 组件,你可以根据需要自定义。

如果你创建的资源并没有在导航菜单中显示,很可能是因为你的模型策略viewAny() 方法并没有返回 true

简易(模态框)资源

有时候,你的模型过于简单,因此你只想在单个页面中管理记录。这种情况下你可以使用模态框进行创建,编辑和删除记录。要生成这样一个带有模态框的简易资源:

php artisan make:filament-resource Customer --simple

你的资源有一个管理(Manage)页面,该页面是一个带有模态框的列表页。

另外,你的资源类不再会有 getRelations() 方法,因为关系管理器只会在编辑页和查看页中展示,不会出现在简易资源中。其他方面则与普通资源相同。

自动生成表单和表格

如果你要节约时间,Filament 也可以基于你模型数据库的字段,为你自动生成一些表单表格,请使用 --generate

php artisan make:filament-resource Customer --generate

如果数据库表中含有 ENUM 字段,doctrine/dbal 包将无法扫描表格且会崩溃。因此 Filament 无法据此为资源生成 schema。更多详情查阅此处

处理软删除

默认情况下,你不能在应用中和已删除的记录进行交互。如果你想要在资源中添加恢复(restore)、强制删除和过滤垃圾记录等功能,可以在生成资源的时候使用 --soft-deletes 标志:

php artisan make:filament-resource Customer --soft-deletes

你点击此处查阅更多关于软删除功能。

生成查看页面

默认情况下,资源只会生成列表页,新建页和编辑页。如果你也想要生成查看页,请使用 --view 标志:

php artisan make:filament-resource Customer --view

记录标题

你可以为资源设置 $recordTitleAttribute 属性,该属性对应模型上的字段名,可以用于将其与其他模型区别开来。(译者:此处直译,意思是大体是在搜索时用以确认某条记录的唯一性。)

比如,它可以是博客文章的标题(title) 或者客户的名字(name):

protected static ?string $recordTitleAttribute = 'name';

此属性需要启用全局搜索特性才有效。

如果某个单一字段无法有效识别一条记录,你可以指定一个 Eloquent 获取器的名称。

资源表单

资源类中包含着一个 form() 方法,用于为新建编辑页面创建表单:

use Filament\Forms;
use Filament\Forms\Form;

public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\TextInput::make('name')->required(),
Forms\Components\TextInput::make('email')->email()->required(),
// ...
]);
}

schema() 方法用于定义表单结构。它是一个表单控件布局组件数组,按照显示顺序在表单中排序。

关于如何使用 Filament 创建表单,请查阅表单文档向导

基于当前操作中隐藏组件

表单组件的 hiddenOn() 方法让你可以基于当前页面或操作动态隐藏字段组件。

此例中,我们在 edit 编辑页面中隐藏了 password 字段:

use Livewire\Component;

Forms\Components\TextInput::make('password')
->password()
->required()
->hiddenOn('edit'),

此外,还有一个 visibleOn() 快捷方法,用来在页面或 Action 中显示字段:

use Livewire\Component;

Forms\Components\TextInput::make('password')
->password()
->required()
->visibleOn('create'),

资源表格

Resource 类包含一个静态 table() 方法,用以在列表页中创建表格:

use Filament\Tables;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;

public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('name'),
Tables\Columns\TextColumn::make('email'),
// ...
])
->filters([
Tables\Filters\Filter::make('verified')
->query(fn (Builder $query): Builder => $query->whereNotNull('email_verified_at')),
// ...
])
->actions([
Tables\Actions\EditAction::make(),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),
]),
]);
}

请查阅表格构造器文档,了解如何添加表格列、过滤器、Action 等。

授权

关于授权,Filament 会监听所有应用中注册的模型策略。使用如下方法:

  • viewAny() 用于完全从导航菜单中隐藏资源,阻止用户访问任何页面。
  • create() 用于控制新建记录
  • update() 用于控制编辑记录
  • view() 用于控制查看记录
  • delete() 用于阻止单条记录被删除。deleteAny() 用于防止记录被批量删除。Filament 使用 deleteAny() 方法因为通过迭代检查 delete() 策略性能不是很好。
  • forceDelete() 用于防止单条软删除记录被强制删除。forceDeleteAny() 用于防止记录被批量强制删除。Filament 之所以使用 forceDeleteAny() 因为在多条记录中迭代检查 forceDelete() 策略性能不佳。
  • restore() 用于防止单条软删除记录被强制恢复。 restoreAny() 用于防止记录被批量强制删除。Filament 之所以使用 restoreAny() 因为在多条记录中迭代检查 restore() 策略性能不佳。
  • reorder() 用于控制重新排序

跳过授权

如果你想让某个资源跳过授权,可以将 $shouldSkipAuthorization 属性设置为 true

protected static bool $shouldSkipAuthorization = true;

自定义模型标签

每个资源都有一个基于模型名自动生成的"模型标签(model label)"。比如,App\Models\Customer 有一个 Customer 标签。

该标签用在 UI 的多个位置中,你可以使用 $modelLabel 属性对其进行自定义:

protected static ?string $modelLabel = 'cliente';

此外,你也可以使用 getModelLabel() 方法去定义动态标签:

public static function getModelLabel(): string
{
return __('filament/resources/customer.label');
}

自定义复数模型标签

资源同时有一个基于模型标签自动生成的"复数模型标签(plural model label)"。比如,customer 标签的复数是 customers

你可以使用 $pluralModelLabel 属性自定义标签的复数版本:

protected static ?string $pluralModelLabel = 'clientes';

此外,你可以在 getPluralModelLabel() 方法中设置动态复数标签:

public static function getPluralModelLabel(): string
{
return __('filament/resources/customer.plural_label');
}

资源导航项

Filament 会使用复数标签为资源自动生成导航菜单项。

如果你想自定义导航项标签,你可以使用 $navigationLabel 属性:

protected static ?string $navigationLabel = 'Mis Clientes';

此外,你可以在 getNavigationLabel() 设置为动态导航标签:

public static function getNavigationLabel(): string
{
return __('filament/resources/customer.navigation_label');
}

设置资源导航图标

$navigationIcon 属性支持任何 Blade 模板组件名。默认情况下,Filament 安装了 Heroicons。不过,你可以创建自定义图标组件或者安装其他图标库。

protected static ?string $navigationIcon = 'heroicon-o-user-group';

此外,你可以在 getNavigationIcon() 方法椎间盘美国设置动态导航图标:

public static function getNavigationIcon(): ?string
{
return 'heroicon-o-user-group';
}

资源导航项排序

$navigationSort 属性让你可以指定导航项的排列顺序:

protected static ?int $navigationSort = 2;

此外,在 getNavigationSort() 方法中你可以动态设置导航项排序:

public static function getNavigationSort(): ?int
{
return 2;
}

导航菜单分组

你可以通过 $navigationGroup 属性对导航菜单进行分组:

protected static ?string $navigationGroup = 'Shop';

此外,你也可以使用 getNavigationGroup() 方法设置动态分组标签:

public static function getNavigationGroup(): ?string
{
return __('filament/navigation.groups.shop');
}

为资源页生成 URL

Filament 在资源类中使用 getUrl() 静态方法,用来为资源和特定页面生成 URL。一般来说,你需要手动或使用 Laravel 的 route() 帮助函数来构建 URL,而这些方法依赖于对资源的 slug 或路由命名规范的了解。

不带任何参数的 getUrl() 方法,将会为资源列表页生成 URL:

use App\Filament\Resources\CustomerResource;

CustomerResource::getUrl(); // /admin/customers

你可以为资源中的指定页面生成 URL。每个页面的名字是资源 getPages() 数组中的数组键名。比如,要为新建页生成 URL:

use App\Filament\Resources\CustomerResource;

CustomerResource::getUrl('create'); // /admin/customers/create

getPages() 方法中的一些页面使用了 URL 参数[比如,record]。要为这些页面生成 URL,并传入记录,你可以使用第二个参数:

use App\Filament\Resources\CustomerResource;

CustomerResource::getUrl('edit', ['record' => $customer]); // /admin/customers/edit/1

本例中,$customer 可以是一个 Eloquent 模型对象,或者 ID。

如果你的应用中有多个面板,getUrl() 将会在当前面板生成一个 URL。你也可以传入面板给 panel 参数,说明该资源应该关联到哪个面板:

use App\Filament\Resources\CustomerResource;

CustomerResource::getUrl(panel: 'marketing');

自定义资源 Eloquent 查询

在 Filament 中,每个资源模型的查询都会从 getEloquentQuery() 方法开始。

因此,可以很容易使用你自己的查询约束或影响整个资源的模型范围(scope)查询

public static function getEloquentQuery(): Builder
{
return parent::getEloquentQuery()->where('is_active', true);
}

禁用全局范围查询

默认情况下,Filament 会监听所有注册到模型的全局范围查询。不过,如果你想要获取比如软删除记录时,这可能不是理想的方案。

要解决此问题,你可以重写 getEloquentQuery() 方法:

public static function getEloquentQuery(): Builder
{
return parent::getEloquentQuery()->withoutGlobalScopes();
}

此外,你也可以移除指定的全局范围查询:

public static function getEloquentQuery(): Builder
{
return parent::getEloquentQuery()->withoutGlobalScopes([ActiveScope::class]);
}

更多关于移除全局范围查询的内容,可以查看 Laravel 文档

自定义资源 URL

默认情况下,Filament 会基于资源名称生成 URL。你可以在资源上设置 $slug 属性对其进行自定义:

protected static ?string $slug = 'pending-orders';

删除资源页

如果你要从你的资源(resource)中删除一个页面,你只需要删除资源 Pages 目录下的对应文件,以及它在 getPages() 方法下的入口。

比如,你有一个资源不想让任何人添加记录。删除 Create 页面文件,然后在 getPages() 中将其移除:

public static function getPages(): array
{
return [
'index' => Pages\ListCustomers::route('/'),
'edit' => Pages\EditCustomer::route('/{record}/edit'),
];
}