Skip to content
全部文档

构建面板插件

前言

继续之前,请先阅读 面板插件开发快速开始指南

简介

本教程将构建一个简单插件,向表单添加一个新字段;该字段也会在用户的面板中可用。

本插件最终代码见 https://github.com/awcodes/clock-widget

步骤 1:创建插件

首先,按快速开始指南中的步骤创建插件。

步骤 2:清理

接下来清理插件,移除不需要的样板代码。看起来很多,但本插件很简单,可去掉大量样板。

删除以下目录与文件:

  1. config
  2. database
  3. src/Commands
  4. src/Facades
  5. stubs

由于插件没有设置项或额外功能方法,也可删除 ClockWidgetPlugin.php 文件。

  1. ClockWidgetPlugin.php

Filament 建议用户用自定义 Filament theme 为插件设置样式,因此我们删除插件内使用 CSS 所需的文件。这是可选的,你仍可使用 CSS,但不推荐。

  1. resources/css
  2. postcss.config.js

现在清理 composer.json,移除不需要的选项。

json
"autoload": {
    "psr-4": {
        // We can remove the database factories
        "Awcodes\\ClockWidget\\Database\\Factories\\": "database/factories/"
    }
},
"extra": {
    "laravel": {
        // We can remove the facade
        "aliases": {
            "ClockWidget": "Awcodes\\ClockWidget\\Facades\\ClockWidget"
        }
    }
},

最后一步是更新 package.json,移除不需要的选项。将 package.json 内容替换为:

json
{
    "private": true,
    "type": "module",
    "scripts": {
        "dev": "node bin/build.js --dev",
        "build": "node bin/build.js"
    },
    "devDependencies": {
        "esbuild": "^0.17.19"
    }
}

然后安装依赖。

bash
npm install

也可删除 Testing 相关目录与文件;本例暂时保留且不会使用。我们强烈建议你为插件编写测试。

步骤 3:配置 provider

插件清理完成后即可开始写代码。src/ClockWidgetServiceProvider.php 中的样板较多,我们全部删掉从头开始。

INFO

本例将注册一个 async Alpine component。这类资源仅按需加载,可在 packageBooted() 中照常注册。若注册的是无论是否使用都会在每页加载的资源(如 CSS 或 JS),应在 Plugin 配置对象的 register() 方法中用 $panel->assets() 注册。否则若在 packageBooted() 中注册,它们会在每个面板加载,无论该面板是否注册了该插件。

我们需要把 Widget 注册到面板,并在使用小部件时加载 Alpine 组件。为此,在 service provider 的 packageBooted 方法中加入如下内容:将 widget 组件注册到 Livewire,并将 Alpine 组件注册到 Filament Asset Manager。

php
use Filament\Support\Assets\AlpineComponent;
use Filament\Support\Facades\FilamentAsset;
use Livewire\Livewire;
use Spatie\LaravelPackageTools\Package;
use Spatie\LaravelPackageTools\PackageServiceProvider;

class ClockWidgetServiceProvider extends PackageServiceProvider
{
    public static string $name = 'clock-widget';

    public function configurePackage(Package $package): void
    {
        $package->name(static::$name)
            ->hasViews()
            ->hasTranslations();
    }

    public function packageBooted(): void
    {
        Livewire::component('clock-widget', ClockWidget::class);

        // Asset Registration
        FilamentAsset::register(
            assets:[
                 AlpineComponent::make('clock-widget', __DIR__ . '/../resources/dist/clock-widget.js'),
            ],
            package: 'awcodes/clock-widget'
        );
    }
}

步骤 4:创建小部件

现在可以创建小部件。先在 ClockWidget.php 中继承 Filament 的 Widget 类,并指定视图位置。由于用 PackageServiceProvider 注册视图,可用 :: 语法告诉 Filament 视图位置。

php
use Filament\Widgets\Widget;

class ClockWidget extends Widget
{
    protected static string $view = 'clock-widget::widget';
}

接下来为小部件创建视图。在 resources/views/widget.blade.php 新建文件并加入如下代码。我们使用 Filament 的 Blade 组件以节省编写 HTML 的时间。

我们使用 async Alpine 加载 Alpine 组件,因此需在 div 上添加 x-load 属性,告诉 Alpine 加载该组件。详见文档的 Core Concepts 一节。

blade
<x-filament-widgets::widget>
    <x-filament::section>
        <x-slot name="heading">
            {{ __('clock-widget::clock-widget.title') }}
        </x-slot>

        

            <p>{{ __('clock-widget::clock-widget.description') }}</p>
            <p class="text-xl" x-text="time"></p>
        

    </x-filament::section>
</x-filament-widgets::widget>

接下来在 src/js/index.js 编写 Alpine 组件,并用 npm run build 构建资源。

js
export default function clockWidget() {
    return {
        time: new Date().toLocaleTimeString(),
        init() {
            setInterval(() => {
                this.time = new Date().toLocaleTimeString();
            }, 1000);
        }
    }
}

还应为小部件中的文本添加翻译,方便用户译成自己的语言。将翻译加到 resources/lang/en/widget.php

php
return [
    'title' => 'Clock Widget',
    'description' => 'Your current time is:',
];

步骤 5:更新 README

请更新 README.md,加入插件安装说明以及希望与用户分享的其他信息,例如如何在项目中使用。例如:

php
// Register the plugin and/or Widget in your Panel provider:

use Awcodes\ClockWidget\ClockWidgetWidget;

public function panel(Panel $panel): Panel
{
    return $panel
        ->widgets([
            ClockWidgetWidget::class,
        ]);
}

就这样,用户现在可以安装并在项目中使用我们的插件了。