尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Filament 4 中基于 spatie/laravel-settings 构建数据库化设置页:SettingsPage 插件完全指南

Filament 4 中基于 spatie/laravel-settings 构建数据库化设置页:SettingsPage 插件完全指南 Filament 4 中基于 spatie/laravel-settings 构建数据库化设置页SettingsPage 插件完全指南【免费下载链接】filamentA powerful open-source UI framework for Laravel • Build and ship apps admin panels fast with Livewire项目地址: https://gitcode.com/GitHub_Trending/fi/filament本篇指南基于 Filament 仓库内的spatie-laravel-settings-plugin插件文档与源码系统讲解如何把spatie/laravel-settings的设置类接入 Filament 面板从 Composer 安装、make:filament-settings-page命令的完整参数到表单自动填充/保存的底层调用链、canAccess()/canEdit()授权策略与翻译发布。读完你能独立搭建一个带数据库持久化的设置页并理解其表单填充、校验、事务与通知的实现细节。一、插件定位与安装该插件位于仓库的 packages/spatie-laravel-settings-plugin 目录其作用只有一个提供Filament\Pages\SettingsPage页面基类让 Filament 页面可以直接读写由spatie/laravel-settings包管理的数据库设置。从 composer.json 可以确认依赖约束PHP^8.2filament/filament: self.version即必须与 Filament 主包同版本当前为 4.xspatie/laravel-settings: ^3.0。安装命令如下来自插件 READMEcomposer require filament/spatie-laravel-settings-plugin:^4.0 -W服务提供者 SpatieLaravelSettingsPluginServiceProvider 在控制台环境下注册make:filament-settings-page命令并加载resources/lang下的翻译文件语言包分组为filament-spatie-laravel-settings-plugin仓库内已内置en、es、pt、ru、ja、ar等数十种语言。二、准备设置类与数据库迁移在创建设置页之前需要先在app/Settings目录中创建设置类并为其创建数据库迁移。设置类需要继承spatie/laravel-settings包的Spatie\LaravelSettings\Settings类——这一点可以从命令源码得到印证MakeSettingsPageCommand.php 在交互式询问时正是用discover_app_classes(parentClass: Settings::class)扫描应用中所有继承自Spatie\LaravelSettings\Settings的类供开发者选择。仓库测试中的设置类示例见 tests/src/Fixtures/Settings/SiteSettings.php测试用site_name、site_description、site_active三个属性。一个细节值得注意命令解析设置类时并不硬编码app/Settings而是读取配置项config(settings.setting_class_path, app_path(Settings))见 MakeSettingsPageCommand.php#L162。这意味着如果你在项目里自定义了设置类的存放路径spatie/laravel-settings包本身支持该配置命令也能正确找到它。三、生成设置页make:filament-settings-page 命令详解README 给出的基本用法php artisan make:filament-settings-page ManageFooter FooterSettings其中第二个参数是你位于app/Settings目录下的FooterSettings类。命令会在app/Filament/Pages目录生成新的设置页类并写入protected static string $settings FooterSettings::class;3.1 命令参数与选项从 MakeSettingsPageCommand.php 可以看到完整签名参数 / 选项说明name位置参数可选页面类名支持目录前缀如Admin/ManageSettingssettings位置参数可选设置类名位于设置目录或完全限定名--cluster/-C在指定 Cluster集群中创建页面--generate/-G根据设置类的属性反射生成表单 schema见第四节--panel指定面板多面板项目中必需--force/-F目标文件已存在时强制覆盖命令还注册了别名filament:settings、filament:settings-page、make:filament-settings见 别名定义。当参数缺省时命令会进入交互模式用text()询问页面名用suggest()让你从扫描出的设置类中搜索选择若面板配置了多个页面命名空间还会用search()询问生成位置。生成完成后若面板未配置pages()/discoverPages()命令会提示你需要手动注册该页面。3.2$settings属性的推导逻辑生成器 SettingsPageClassGenerator 会把设置类写为protected static string $settings静态属性。如果你手写页面而忘记声明该属性基类也有兜底逻辑——SettingsPage::getSettings() 会按类名推导取页面类基名截掉末尾的Settings前缀App\Settings\再补上Settings。例如ManageFooterSettings会推导出App\Settings\FooterSettings。测试用例 tests/src/SpatieSettingsPlugin/SettingsPageTest.php#L82-L84 验证了这条推导链it(derives settings class name when $settings is not set, function (): void { expect(DerivedGeneralSettings::getSettings())-toBe(App\\Settings\\DerivedGeneralSettings); });四、-G选项从设置类属性反射生成表单--generate选项是 README 未展开、但源码中实现很完整的能力。SettingsPageClassGenerator::getFormComponents() 通过 PHP 反射遍历设置类的所有公共、非静态属性按类型映射为表单组件属性类型 / 特征生成的组件boolToggle实现DateTimeInterface的类型含联合类型DateTimePicker属性名包含image忽略大小写FileUpload并启用-image()Enum含联合类型中的 EnumSelectoptions自动指向该 Enum 类其他默认TextInput在默认TextInput上还有若干启发式规则属性名含email时追加-email()含password追加-password()含phone/tel追加-tel()float/int属性含联合类型会追加-numeric()整型再追加-integer()若属性名为cost、money、price或以_cost、_price结尾还会加上$前缀非可空属性!$propertyType-allowsNull()自动追加-required()特殊键名id、sku、uuid会被赋予大写标签。也就是说如果你的FooterSettings类写成这样class FooterSettings extends Settings { public string $copyright; public bool $show_social_links false; public DateTimeInterface $maintenance_start; public array $links []; }执行php artisan make:filament-settings-page ManageFooter FooterSettings --generate即可得到一个包含TextInput、Toggle、DateTimePicker的初始表单再手工补充Repeater等复杂结构即可。五、构建表单字段名即属性名README 的核心约定每个表单字段名必须与设置类上的属性名一一对应。官方示例继承自插件文档use Filament\Forms\Components\Repeater; use Filament\Forms\Components\TextInput; use Filament\Schemas\Schema; public function form(Schema $schema): Schema { return $schema -components([ TextInput::make(copyright) -label(Copyright notice) -required(), Repeater::make(links) -schema([ TextInput::make(label)-required(), TextInput::make(url) -url() -required(), ]), ]); }由于 Panel Builder 默认安装了 Form Builder你可以自由使用任意表单字段与布局组件。仓库测试中的完整页面示例见 tests/src/Fixtures/Pages/ManageSiteSettings.phpclass ManageSiteSettings extends SettingsPage { protected static string $settings SiteSettings::class; protected static string | BackedEnum | null $navigationIcon Heroicon::OutlinedCog6Tooth; public function form(Schema $schema): Schema { return $schema -schema([ TextInput::make(site_name)-required(), TextInput::make(site_description), Toggle::make(site_active), ]); } }表单自动填充、自动保存并非魔法其调用链可从 SettingsPage.php 源码完整还原5.1 页面加载mount → fillFormmount()在 Livewire 挂载时调用fillForm()L35-L38fillForm()依次触发beforeFillHook →app(static::getSettings())从容器中解析设置类 →$settings-toArray()序列化为数组 → 经mutateFormDataBeforeFill()变换 →$this-form-fill($data)灌入表单 →afterFillHookL40-L51。5.2 保存save 的完整事务链save()方法L62-L108的执行顺序权限闸门if (! $this-canEdit()) return;——不可编辑时直接短路开启数据库事务beginDatabaseTransaction()来自CanUseDatabaseTransactionstrait校验beforeValidate→$this-form-getState()触发 Laravel 表单校验→afterValidate数据变换mutateFormDataBeforeSave($data)供你在落库前改写数据落库$settings-fill($data); $settings-save();再触发afterSaveHook异常处理捕获Halt异常时按shouldRollbackDatabaseTransaction()决定回滚或提交其他异常一律回滚并向上抛出收尾rememberData()标记数据已保存配合HasUnsavedDataChangesAlerttrait 消除未保存更改提示→ 发送保存成功通知 → 若getRedirectUrl()返回地址则重定向SPA 模式下走FilamentView::hasSpaMode()的导航。保存动作本身是页面上的一个ActiongetSaveFormAction()名为save绑定mods快捷键Cmd/CtrlS 保存且-visible($this-canEdit())——即无编辑权限时按钮直接不显示。表单本体由defaultForm()配置L180-L187双列布局、内联标签、状态绑定到 Livewire 的$data属性并且-disabled(! $this-canEdit())——这就是只读设置页的底层实现整个表单被禁用用户只能看不能改。页面还内置了一组可用 Hook 供子类扩展beforeFill、afterFill、beforeValidate、afterValidate、beforeSave、afterSave均在fillForm()/save()中以$this-callHook(...)触发。此外两个空实现钩子方法mutateFormDataBeforeFill()与mutateFormDataBeforeSave()是官方预留的数据变换点。六、授权canAccess 与 canEdit 的两级门禁README 对授权的描述可以结合源码精确化。Filament 页面对canAccess()的调用由面板路由层统一处理返回false时该页面不可访问、不出现在导航中。插件默认不做任何限制SettingsPage未覆写canAccess()沿用Page基类的默认true。要整体禁止访问某设置页public static function canAccess(): bool { return auth()-user()-isAdmin(); }若用户可访问但不可编辑例如只允许查看当前配置覆写 SettingsPage::canEdit()基类默认返回truepublic static function canEdit(): bool { return auth()-user()-isAdmin(); }canEdit()在源码中有三处生效点save()开头短路保存请求、getSaveFormAction()控制保存按钮可见性、defaultForm()中-disabled()禁用整表。注意README 原文警告canEdit()只拦截保存——它并不能阻止用户加载页面并读到每个字段的当前值。如果设置本身敏感API 密钥、内部开关等应通过canAccess()以及/或路由中间件限制查看而不是依赖canEdit()。七、发布翻译如需本地化插件内置的界面文案保存按钮、成功通知等执行php artisan vendor:publish --tagfilament-spatie-laravel-settings-plugin-translations文案引用格式为filament-spatie-laravel-settings-plugin::pages/settings-page.*例如成功通知标题键为pages/settings-page.notifications.saved.title见 SettingsPage.php#L125。仓库中翻译源文件位于 packages/spatie-laravel-settings-plugin/resources/lang 目录你也可据此自定义通知文案覆写getSavedNotificationTitle()返回自定义标题或返回空值以完全关闭通知。八、测试设置页实战验证仓库自带的 Pest 测试 tests/src/SpatieSettingsPlugin/SettingsPageTest.php 给出了验证设置页的标准姿势可直接照搬进自己的项目beforeEach(function (): void { DB::table(spatie_settings)-insert([ [group site, name site_name, locked false, payload json_encode(My Site)], // ... ]); $this-actingAs(User::factory()-create()); }); it(can retrieve data, function (): void { livewire(ManageSiteSettings::class) -assertFormSet([ site_name My Site, site_active true, ]); }); it(can save, function (): void { livewire(ManageSiteSettings::class) -fillForm([site_name Updated Site, site_active false]) -call(save) -assertHasNoFormErrors(); $settings app(SiteSettings::class); expect($settings-site_name)-toBe(Updated Site); }); it(can validate input on save, function (): void { livewire(ManageSiteSettings::class) -fillForm([site_name ]) -call(save) -assertHasFormErrors([site_name required]); }); it(sends a notification after saving, function (): void { livewire(ManageSiteSettings::class) -fillForm([...]) -call(save) -assertNotified(); });这组测试恰好覆盖了本指南的四个关键能力数据从数据库读入表单assertFormSet、表单状态经call(save)落库回读、字段校验在保存前生效、保存后触发通知。九、小结关键文件速查关注点文件插件 README本文主体来源packages/spatie-laravel-settings-plugin/README.mdSettingsPage基类fill/save/Hook/授权packages/spatie-laravel-settings-plugin/src/Pages/SettingsPage.php生成命令与参数packages/spatie-laravel-settings-plugin/src/Commands/MakeSettingsPageCommand.php反射生成表单的逻辑packages/spatie-laravel-settings-plugin/src/Commands/FileGenerators/SettingsPageClassGenerator.php服务提供者命令注册、翻译加载packages/spatie-laravel-settings-plugin/src/SpatieLaravelSettingsPluginServiceProvider.php测试与页面 Fixturetests/src/SpatieSettingsPlugin/SettingsPageTest.php、tests/src/Fixtures/Pages/ManageSiteSettings.php使用前提提醒该插件仅适用于 Filament 4PHP ≥ 8.2spatie/laravel-settings≥ 3.0且设置页本质是 Livewire 页面需要用户在面板中已登录并满足canAccess()才能访问。【免费下载链接】filamentA powerful open-source UI framework for Laravel • Build and ship apps admin panels fast with Livewire项目地址: https://gitcode.com/GitHub_Trending/fi/filament创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表