Languages

Version

Theme

插件

插件开发

简介

Filament 插件的基础是 Laravel 包。它们通过 Composer 安装到你的 Filament 项目中,并遵循所有标准技术,例如使用服务提供者注册路由、视图和翻译。如果你是 Laravel 包开发的新手,这里有一些资源可以帮助你掌握核心概念:

Filament 插件基于 Laravel 包的概念创建,允许你为任何 Filament 面板提供和使用可重用的功能。它们可以一次性添加到每个面板中,并且可以根据的差异进行配置。

使用插件类配置面板

插件类用于允许包与面板配置集成。它是一个简单 PHP 类,实现了 Plugin 接口。需要有 3 个方法:

  • getId() 方法返回区别于其他插件的唯一标识符。请确保它足够特别,而不至于与项目中的其他插件产生冲突。
  • register() 方法允许你使用任何可用于面板的配置选项。包括注册资源自定义页面主题渲染钩子等。
  • boot() 方法只有在插件注册的面板实际被用到时才会运行。它由中间件类执行。.
<?php

namespace DanHarrin\FilamentBlog;

use DanHarrin\FilamentBlog\Pages\Settings;
use DanHarrin\FilamentBlog\Resources\CategoryResource;
use DanHarrin\FilamentBlog\Resources\PostResource;
use Filament\Contracts\Plugin;
use Filament\Panel;

class BlogPlugin implements Plugin
{
    public function getId(): string
    {
        return 'blog';
    }

    public function register(Panel $panel): void
    {
        $panel
            ->resources([
                PostResource::class,
                CategoryResource::class,
            ])
            ->pages([
                Settings::class,
            ]);
    }

    public function boot(Panel $panel): void
    {
        //
    }
}

通过实例化插件类并将其传递给配置plugin() 方法,插件用户可以将其添加到面板中:

use DanHarrin\FilamentBlog\BlogPlugin;

public function panel(Panel $panel): Panel
{
    return $panel
        // ...
        ->plugin(new BlogPlugin());
}

流畅地实例化插件类

你可能希望在插件类中添加 make() 方法,以为用户提供流畅的接口来实例化它。此外,通过容器 (app()) 来实例化插件对象,可以在运行时用不同的实现替换:

use Filament\Contracts\Plugin;

class BlogPlugin implements Plugin
{
    public static function make(): static
    {
        return app(static::class);
    }
    
    // ...
}

现在,用户可以使用 make() 方法:

use DanHarrin\FilamentBlog\BlogPlugin;
use Filament\Panel;

public function panel(Panel $panel): Panel
{
    return $panel
        // ...
        ->plugin(BlogPlugin::make());
}

为每个面板配置插件

你可以在插件类中添加其他方法,允许你的用户对其进行配置。我们建议你为提供的每个选项添加一个 setter 和一个 getter 方法。你应该使用一个属性将首选项存储在 setter 中,并在 getter 中再次检索它:

use DanHarrin\FilamentBlog\Resources\AuthorResource;
use Filament\Contracts\Plugin;
use Filament\Panel;

class BlogPlugin implements Plugin
{
    protected bool $hasAuthorResource = false;
    
    public function authorResource(bool $condition = true): static
    {
        // This is the setter method, where the user's preference is
        // stored in a property on the plugin object.
        $this->hasAuthorResource = $condition;
    
        // The plugin object is returned from the setter method to
        // allow fluent chaining of configuration options.
        return $this;
    }
    
    public function hasAuthorResource(): bool
    {
        // This is the getter method, where the user's preference
        // is retrieved from the plugin property.
        return $this->hasAuthorResource;
    }
    
    public function register(Panel $panel): void
    {
        // Since the `register()` method is executed after the user
        // configures the plugin, you can access any of their
        // preferences inside it.
        if ($this->hasAuthorResource()) {
            // Here, we only register the author resource on the
            // panel if the user has requested it.
            $panel->resources([
                AuthorResource::class,
            ]);
        }
    }
    
    // ...
}

此外,你可以使用插件的唯一 ID,在插件类外访问其配置选项。为此,请将 ID 传入到 filament() 方法中:

filament('blog')->hasAuthorResource()

访问配置时,你可能希望有更好的类型安全和 IDE 自动补全。这完全取决于你如何实现,但其中一个方式可能是在插件类中添加一个静态方法来检索它:

use Filament\Contracts\Plugin;

class BlogPlugin implements Plugin
{
    public static function get(): static
    {
        return filament(app(static::class)->getId());
    }
    
    // ...
}

现在,你可以使用新的静态方法来访问插件配置:

BlogPlugin::get()->hasAuthorResource()

在插件中分发面板

在 Laravel 包中分发整个面板非常容易。这样,用户可以简单地安装你的插件,并预先构建其应用的全新部分。

当配置面板时,配置类扩展了 PanelProvider 类,这是一个标准的 Laravel 服务提供者。你可以将其用作包的服务提供者:

<?php

namespace DanHarrin\FilamentBlog;

use Filament\Panel;
use Filament\PanelProvider;

class BlogPanelProvider extends PanelProvider
{
    public function panel(Panel $panel): Panel
    {
        return $panel
            ->id('blog')
            ->path('blog')
            ->resources([
                // ...
            ])
            ->pages([
                // ...
            ])
            ->widgets([
                // ...
            ])
            ->middleware([
                // ...
            ])
            ->authMiddleware([
                // ...
            ]);
    }
}

然后,你应该在包的 composer.json 中将其注册为服务提供者:

"extra": {
    "laravel": {
        "providers": [
            "DanHarrin\\FilamentBlog\\BlogPanelProvider"
        ]
    }
}
Edit on GitHub

Still need help? Join our Discord community or open a GitHub discussion

Previous
开始