扩展插件开发
扩展插件可用于扩展 Filament 的默认行为,创建多个应用中都可复用的模块。
要创建一个新的插件,需要继承 Filament 提供的 Filament\PluginServiceProvider
类:
use Filament\PluginServiceProvider;
use Spatie\LaravelPackageTools\Package;
class ExampleServiceProvider extends PluginServiceProvider
{
public function configurePackage(Package $package): void
{
$package->name('your-package-name');
}
// ...
}
PluginServiceProvider
继承了 Larave l扩展包工具提供的服务提供者,因此所有后者 configurePackage()
可用的选项在此处也是可用。
插件(Plugin)必须有唯一的 name 属性。
注册插件
应用插件
如果你为一个特定应用开发了一个插件,你必须在 config/app.php
文件中注册新的服务提供者:
return [
'providers' => [
// ...
\App\Providers\ExampleServiceProvider::class,
]
];
Laravel 会在启动时加载你的服务提供者,你的插件会被初始化。
分发插件
就像普通的 Laravel 扩展包,你应该将你的服务提供者的全限定类名到 composer.json
文件的 extra.laravel.provider
数组中:
{
"extra": {
"laravel": {
"providers": [
"Vendor\\Package\\ExampleServiceProvider"
]
}
}
}
这能确保你的服务提供者在包安装后由 Laravel 自动加载。
资源类
要注册自定义的资源类,将全限定类名添加到服务提供者的 $resources
属性数组中:
use Filament\PluginServiceProvider;
use Spatie\LaravelPackageTools\Package;
use Vendor\Package\Resources\CustomResource;
class ExampleServiceProvider extends PluginServiceProvider
{
protected array $resources = [
CustomResource::class,
];
public function configurePackage(Package $package): void
{
$package->name('your-package-name');
}
}
Filament 会自动注册这个 Resource
,保证 Livewire 能找到他。
页面
要去注册自定义页面,将全限定类名添加到服务提供者的 $pages
属性数组中:
use Filament\PluginServiceProvider;
use Spatie\LaravelPackageTools\Package;
use Vendor\Package\Pages\CustomPage;
class ExampleServiceProvider extends PluginServiceProvider
{
protected array $pages = [
CustomPage::class,
];
public function configurePackage(Package $package): void
{
$package->name('your-package-name');
}
}
Filament 会自动注册这个 Page
,确保 Livewire 能找到他。
页内插件
要去注册自定义页内插件(Widgets),将全限定类名添加到服务提供者的 $widgets
属性数组中:
use Filament\PluginServiceProvider;
use Spatie\LaravelPackageTools\Package;
use Vendor\Package\Widgers\CustomWidget;
class ExampleServiceProvider extends PluginServiceProvider
{
protected array $widgets = [
CustomWidget::class,
];
public function configurePackage(Package $package): void
{
$package->name('your-package-name');
}
}
Filament 会自动注册这个 Widget
,保证 Livewire 找到他。
前端资源
Filament 插件也可以注册他自己的前端资源。这些资源会被所有 Filament 相关的 页面引入,允许你使用自己的 CSS 和 JavaScript。
CSS样式表
要去注册自定义页面,将全限定类名添加到服务提供者的 $styles
属性数组中。你应该使用唯一名称作为键名,指向样式表的 URL 作为值。
use Filament\PluginServiceProvider;
use Spatie\LaravelPackageTools\Package;
class ExampleServiceProvider extends PluginServiceProvider
{
protected array $styles = [
'my-package-styles' => __DIR__ . '/../dist/app.css',
];
public function configurePackage(Package $package): void
{
$package->name('your-package-name');
}
}
Tailwind CSS
如果你使用了 Filament 核心中未使用的 Tailwind 类,你需要编译自己的 Tailwind CSS 文件并将其捆绑到插件。按照对应的 Tailwind 指南设置,不过请忽略 @tailwind base
,因为用户自定义主题时这一语句会重写基础样式。
编译后,你的 Tailwind 样式中可能会保函 Filament 核心中已有的类。请使用 awcodes/filament-plugin-purge 将这些类排除(Purge),对其瘦身。
Script 脚本
要去注册自定义页面,将全限定类名添加到服务提供者的 $scripts
属性数组中。你应该使用唯一名称作为键名,指向脚本的 URL 作为值。这些脚本会被添加到 Filament 核心脚本之后。
use Filament\PluginServiceProvider;
use Spatie\LaravelPackageTools\Package;
class ExampleServiceProvider extends PluginServiceProvider
{
protected array $scripts = [
'my-package-scripts' => __DIR__ . '/../dist/app.js',
];
public function configurePackage(Package $package): void
{
$package->name('your-package-name');
}
}
要在 Filament 核心脚本之前添加,请使用 $beforeCoreScripts
属性。如果你想钩入到 Alpine 事件中,这是很有用的。
use Filament\PluginServiceProvider;
use Spatie\LaravelPackageTools\Package;
class ExampleServiceProvider extends PluginServiceProvider
{
protected array $beforeCoreScripts = [
'my-package-scripts' => __DIR__ . '/../dist/app.js',
];
public function configurePackage(Package $package): void
{
$package->name('your-package-name');
}
}
为前端提供数据
在创建插件时,你可能会发现需要在客户端获取一些由服务端生成的数据。
你可以在服务提供者中使用 getScriptData()
方法,返回一个字符串作为键名和值、可以转换成 JSON 数组:
use Filament\PluginServiceProvider;
use Illuminate\Support\Facades\Auth;
use Spatie\LaravelPackageTools\Package;
class ExampleServiceProvider extends PluginServiceProvider
{
public function configurePackage(Package $package): void
{
$package->name('your-package-name');
}
protected function getScriptData(): array
{
return [
'userId' => Auth::id(),
];
}
}
现在你可以在脚本中获取数据:
<script>
console.log(window.filamentData.userId)
</script>
用户菜单
要在你的插件中注册用户菜单项,在服务提供者的 getUserMenuItems()
方法中返回值:
use Filament\PluginServiceProvider;
use Spatie\LaravelPackageTools\Package;
use Vendor\Package\Pages\CustomPage;
class ExampleServiceProvider extends PluginServiceProvider
{
public function configurePackage(Package $package): void
{
$package->name('your-package-name');
}
protected function getUserMenuItems(): array
{
return [
UserMenuItem::make()
->label('Settings')
->url(route('filament.pages.settings'))
->icon('heroicon-s-cog'),
];
}
}
Filament 会自动注册你的 Page
, 确保 Livewire 找到它。
命令, 视图, 翻译, 迁移及其他
由于PluginServiceProvider
继承了Laravel扩展包工具的服务提供者, 你可以使用configurePackage
方法来注册commands, views, translations, migrations 等等。
ServingFilament事件
如果你依赖于 Filament 的 boot()
方法定义的数据或者通过 Filament::serving()
传输的数据,你可以为 Filament\Events\ServingFilament
事件注册监听者(listeners):
use Filament\Events\ServingFilament;
use Filament\PluginServiceProvider;
use Illuminate\Support\Facades\Event;
use Spatie\LaravelPackageTools\Package;
class ExampleServiceProvider extends PluginServiceProvider
{
public function configurePackage(Package $package): void
{
$package->name('your-package-name');
}
public function packageConfiguring(Package $package): void
{
Event::listen(ServingFilament::class, [$this, 'registerStuff']);
}
protected function registerStuff(ServingFilament $event): void
{
// ...
}
}