开始

Resources

资源是用来为模型创建 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 也可以基于你模型数据库的字段,为你自动生成一些表单表格

使用此功能需要安装 doctrine/dbal 包:

composer require doctrine/dbal

现在你可以使用 --generate 来生成资源了:

php artisan make:filament-resource Customer --generate

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

处理软删除

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

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

Note: If your table contains ENUM columns, doctrine/dbal is unable to scan your table and will crash. Hence Filament is unable to generate the schema for your resource if it contains an ENUM column. Read more about this issue here.

生成查看页面

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

php artisan make:filament-resource Customer --view-page

记录标题

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

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

protected static ?string $recordTitleAttribute = 'name';

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

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

表单

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

use Filament\Forms;
use Filament\Resources\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() 方法用于定义表单结构。它是一个表单控件数组,按照显示顺序在表单中排序。

表单的可用字段包括:

查看所有可用表单[控件] fields,请查阅 表单构造器文档.

布局

表单布局完全可以自定义。我们提供了许多布局组件,它们之间可以联合使用:

要查看所有可用布局组件清单,请查阅表单构造器文档

你也可以创建你自己的完全自定义布局组件

根据情况隐藏组件

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

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

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

此外,有一个 visibleOn() 快捷方法用以在指定页面或操作中显示控件。

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

表格

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

use Filament\Resources\Table;
use Filament\Tables;
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\DeleteBulkAction::make(),
]);;
}

查阅列表页文档,可以查看表格字段过滤器操作批量操作等是怎么添加的。

关联

Filament 有多种用于管理资源关联的工具。你可以根据你的实际情况选择使用:

BelongsTo

下拉列表

Filament 有一个专门用于自动从 BelongsTo 关联加载选项的下拉列表控件:

use Filament\Forms\Components\BelongsToSelect;
 
BelongsToSelect::make('author_id')
->relationship('author', 'name')

关于 BelongsToSelect 的更多信息,可以查看表单文档

布局组件

表单布局组件可以用来保存子数据到关联模型,比如 BelongsTo 关联:

use Filament\Forms\Components\Fieldset;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
 
Fieldset::make('Author')
->relationship('author')
->schema([
TextInput::make('name')->required(),
Textarea::make('bio'),
])

更多信息,可以查看表单文档

HasOne

布局组件

表单布局组件可以用来保存子数据到关联模型,比如 HasOne 关联:

use Filament\Forms\Components\Fieldset;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
 
Fieldset::make('Metadata')
->relationship('metadata')
->schema([
TextInput::make('title'),
Textarea::make('description'),
FileUpload::make('image'),
])

更多信息,可以查看表单文档

HasMany

关联管理器

在 Filament 中,“关联管理器(Relation managers)” 允许管理员可以在不必离开资源编辑页面的情况下,展示列表、新建、编辑、删除、关联和取消关联相关记录。

相关的记录在表格中展示,可以通过按钮为每个操作打开一个模态框。

更多关于关联管理器的信息,查看相关文档

Repeater

另外,如果你想在主表单里面对关联(relationship)进行编辑,你也可以使用Repeater

use App\Models\App;
use Filament\Forms\Components\HasManyRepeater;
 
HasManyRepeater::make('qualifications')
->relationship('qualifications')
->schema([
// ...
])

就用户体验而言,此方案仅适用于你关联的模型只有一些有限的字段。否则,表单会变得很长。

HasManyThrough

关联管理器

在 Filament 中,“关联管理器(Relation managers)” 允许管理员可以在不离开资源编辑页面的情况下,展示列表、新建、编辑、删除、关联和取消关联相关记录。

相关的记录在表格中展示,有一些按钮用来让每个操作打开一个模态框。

更多关于关联管理器的信息,查看相关文档

BelongsToMany

多选下拉列表

Filament 有一个专门用于自动从 BelongsToManyMultiSelect 关联加载选项的多选下拉列表控件:

use Filament\Forms\Components\BelongsToManyMultiSelect;
 
BelongsToManyMultiSelect::make('technologies')
->relationship('technologies', 'name')

更多关于 BelongsToManyMultiSelect 的信息,请查看表单文档

复选框列表控件

Filament 有一个专门用于自动从 BelongsToManyCheckboxList 关联加载选项的复选框列表控件:

use Filament\Forms\Components\BelongsToManyCheckboxList;
 
BelongsToManyCheckboxList::make('technologies')
->relationship('technologies', 'name')

更多关于 BelongsToManyCheckboxList 的信息,请查看表单文档.

关联管理器

在 Filament 中,“关联管理器(Relation managers)” 允许管理员可以在不离开资源编辑页面的情况下,展示列表、新建、编辑、删除、关联和取消关联相关记录。

相关的记录在表格中展示,有一些按钮用来让每个操作打开一个模态框。

更多关于关联管理器的信息,查看相关文档

MorphOne

布局组件

表单布局组件可以用来保存子数据到关联模型,比如 MorphOne 关联:

use Filament\Forms\Components\Fieldset;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
 
Fieldset::make('Metadata')
->relationship('metadata')
->schema([
TextInput::make('title'),
Textarea::make('description'),
FileUpload::make('image'),
])

更多信息,请查看表单文档

MorphMany

关联管理器

在 Filament 中,“关联管理器(Relation managers)” 允许管理员可以在不离开资源编辑页面的情况下,展示列表、新建、编辑、删除、关联和取消关联相关记录。

相关的记录在表格中展示,有一些按钮用来让每个操作打开一个模态框。

更多关于关联管理器的信息,查看相关文档

Repeater

另外,如果你想在主表单里面对关联(relationship)进行编辑,你也可以使用Repeater

use App\Models\App;
use Filament\Forms\Components\MorphManyRepeater;
 
MorphManyRepeater::make('qualifications')
->relationship('qualifications')
->schema([
// ...
])

就用户体验而言,此方案仅适用于你关联的模型只有一些有限的字段。否则,表单会变得很长。

MorphToMany

关联管理器

在 Filament 中,“关联管理器(Relation managers)” 允许管理员可以在不离开资源编辑页面的情况下,展示列表、新建、编辑、删除、关联和取消关联相关记录。

相关的记录在表格中展示,有一些按钮用来让每个操作打开一个模态框。

更多关于关联管理器的信息,查看相关文档

授权

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

  • viewAny 用于完全从导航菜单中隐藏资源,阻止用户访问任何页面。
  • create() 用于控制新建记录.
  • update() 用于控制编辑记录.
  • delete() 用于阻止单条记录被删除。deleteAny() 用于防止记录被批量删除。Filament 使用 deleteAny() 方法因为通过迭代检查 delete() 策略性能不是很好。
  • view() 用于控制查看记录.

资源标签

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

这个标签在用户界面的很多地方上使用到了,你也可以使用 $label 属性自定义:

protected static ?string $label = 'cliente';

此外,你也可以使用 getLabel() 来定义动态标签:

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

复数标签

每个资源同时也有一个基于标签自动生成的“复数标签(plural label)”。比如,customer 标签会生成 customers 复数标签。

你也可以使用 $pluralLabel 属性自定义复数标签:

protected static ?string $pluralLabel = 'clientes';

此外,你也可以使用 getPluralLabel() 来定义动态复数标签:

public static function getPluralLabel(): 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 安装了Blade Heroicons包,你可以开箱即用地使用Heroicon的图标名。除此之外,你也可以创建你自己自定义的ICON组件或者安装其他图标库。

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;

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

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

导航菜单分组

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

protected static ?string $navigationGroup = 'Shop';

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

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

自定义Eloquent查询

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

因此,可以很容易使用你自己的模型范围(scope)查询。你可以在后台面板中用它来实现多租户(multi-tenancy)特性。

禁用全局范围查询

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

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

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

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

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

更多关于移除全局范围查询的信息可查阅Laravel文档

Multi-tenancy

多租户(Multi-tenancy),简单地说,就是用户拥有记录,并且只能获取到他们自己的记录。(译者注:让多用户在共用程序组件之时,仍确保各用户见数据的隔离性。)

从头开始实现简单多租户技术

简单的多租户(multi-tenancy)策略在 Filament 中很容易设置。

首先,通过 getEloquentQuery() 方法为每个资源限定基础Eloquent查询范围

public static function getEloquentQuery(): Builder
{
return parent::getEloquentQuery()->whereBelongsTo(auth()->user());
}

此例中,使用 whereBelongsTo() 来限定属于当前认证用户的记录。此外,你可以使用任何你想用的 Eloquent 方法,包括手动的 where() 查询,或者scope范围查询

最好,如果要让新建的记录附加到当前用户上。最简单的办法是使用模型观察者

public function creating(Post $post): void
{
$post->user()->associate(auth()->user());
}

stancl/tenancy

要在 Filament 中使用 stancl/tenancy,你只需要添加 InitializeTenancyByDomain::class 中间件到 LivewireFilament 配置文件即可:

use Stancl\Tenancy\Middleware\InitializeTenancyByDomain;
 
'middleware' => [
// ...
'base' => [
// ...
InitializeTenancyByDomain::class
],
],

删除页面

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

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

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

需要帮助? 加入论坛 或者打开 GitHub讨论

喜欢Filament?

Filament 中文文档由 laravel-filament.cn 翻译整理。站长用爱发电,希望为英文阅读不畅的朋友提供快速掌握Filament框架的途径。文档的翻译,社区的运营维护都需要时间精力上的付出。如果文档社区使你受益,如果你想支持站长...

打赏