默认情况下,Filament Profile 页面很简单。它看起来与登录和注册屏幕非常相似,具有简单直接的界面,没有任何侧菜单或其他元素。
制作定制的 Edit Profile 页面
运行命令: php artisan make:filament-page EditProfile --type=custom
执行该命令将生成两个文件: App\Filament\Pages\EditProfile.php
- 这用作 Livewire 组件的 PHP 类,包含核心逻辑。
resources\filament\pages\edit-profile.blade.php
- 这是前端的视图文件,用于制作用户界面。
随后,是时候重新配置 Filament 面板设置了,将配置文件链接引导到我们新创建的页面。
app/Providers/Filament/AdminPanelProvider.php
:
php
use App\Filament\Pages\EditProfile;
class AdminPanelProvider extends PanelProvider
{
public function panel(Panel $panel): Panel
{
return $panel
->default()
->id('admin')
->path('admin')
->login()
->profile()
->userMenuItems([
'profile' => MenuItem::make()->url(fn (): string => EditProfile::getUrl())
])
// More configurations...
}
}
导航到"编辑个人资料"部分后,迎接您的是一个精美的自定义页面,标题优雅地为"编辑个人资料"。
接下来,让我们使用多个表单来丰富我们的自定义页面。此页面是一个 Livewire 组件,因此您需要使其可用于表单。让我们来探讨一下如何操作。
为表单准备页面 在 Ur app/Filament/Pages/EditProfile.php
中,添加以下内容:
php
use Filament\Forms\Contracts\HasForms;
use Filament\Forms\Concerns\InteractsWithForms;
class EditProfile extends Page implements HasForms
{
use InteractsWithForms;
protected static string $view = 'filament.pages.edit-profile';
protected static bool $shouldRegisterNavigation = false;
}
现在,让我们定义并填写表单。处理多个表单时的主要区别在于使用 getForms()
方法声明表单名称。此方法返回一个表单名称数组,这些名称对应于您需要为每个表单定义的公共属性。
修改EditProfile.php
:
php
use Exception;
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Pages\Page;
use Filament\Pages\Concerns;
use Filament\Actions\Action;
use Filament\Facades\Filament;
use Illuminate\Support\Facades\Hash;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Validation\Rules\Password;
use Illuminate\Contracts\Auth\Authenticatable;
class EditProfile extends Page implements HasForms
{
use InteractsWithForms;
protected static string $view = 'filament.pages.edit-profile';
protected static bool $shouldRegisterNavigation = false;
public ?array $profileData = [];
public ?array $passwordData = [];
public function mount(): void
{
$this->fillForms();
}
protected function getForms(): array
{
return [
'editProfileForm',
'editPasswordForm',
];
}
public function editProfileForm(Form $form): Form
{
return
->schema([
Forms\Components\Section::make('Profile Information')
->description('Update your account\'s profile information and email address.')
->schema([
Forms\Components\TextInput::make('name')
->required(),
Forms\Components\TextInput::make('email')
->email()
->required()
->unique(ignoreRecord: true),
]),
])
->model($this->getUser())
->statePath('profileData');
}
public function editPasswordForm(Form $form): Form
{
return
->schema([
Forms\Components\Section::make('Update Password')
->description('Ensure your account is using long, random password to stay secure.')
->schema([
Forms\Components\TextInput::make('Current password')
->password()
->required()
->currentPassword(),
Forms\Components\TextInput::make('password')
->password()
->required()
->rule(Password::default())
->autocomplete('new-password')
->dehydrateStateUsing(fn ($state): string => Hash::make($state))
->live(debounce: 500)
->same('passwordConfirmation'),
Forms\Components\TextInput::make('passwordConfirmation')
->password()
->required()
->dehydrated(false),
]),
])
->model($this->getUser())
->statePath('passwordData');
}
protected function getUser(): Authenticatable & Model
{
$user = Filament::auth()->user();
if (! $user instanceof Model) {
throw new Exception('The authenticated user object must be an Eloquent model to allow the profile page to update it.');
}
return $user;
}
protected function fillForms(): void
{
$data = $this->getUser()->attributesToArray();
$this->editProfileForm->fill($data);
$this->editPasswordForm->fill();
}
}
在上面的代码片段中,editProfileForm
和 editPasswordForm
是定义每个表单的公共方法。它们的名称对应于您在 getForms()
方法中指定的表单名称。
最后,是时候让这些形式成为众人瞩目的焦点了。修改您的 resources/views/filament/pages/edit-profile.blade.php
:
php
<x-filament-panels::page>
<x-filament-panels::form>
{{ $this->editProfileForm }}
</x-filament-panels::form>
<x-filament-panels::form>
{{ $this->editPasswordForm }}
</x-filament-panels::form>
</x-filament-panels::page>
在设置后返回 Edit Profile 页面后,您将看到两个整齐分割的表单,可供用户交互。然而,这些表格缺乏可操作的按钮。
增强 Filament 中的表单提交
在保存表单数据之前,您需要提供一种启动该过程的方法 --- 通常是提交按钮。
app/Filament/Pages/EditProfile.php
:
php
use Filament\Actions\Action;
class EditProfile extends Page implements HasForms
{
//...
protected function getUpdateProfileFormActions(): array
{
return [
Action::make('updateProfileAction')
->label(__('filament-panels::pages/auth/edit-profile.form.actions.save.label'))
->submit('editProfileForm'),
];
}
protected function getUpdatePasswordFormActions(): array
{
return [
Action::make('updatePasswordAction')
->label(__('filament-panels::pages/auth/edit-profile.form.actions.save.label'))
->submit('editPasswordForm'),
];
}
//...
}
显示提交操作 resources/views/filament/pages/edit-profile.blade.php
:
php
<x-filament-panels::page>
<x-filament-panels::form wire:submit="updateProfile">
{{ $this->editProfileForm }}
<x-filament-panels::form.actions
:actions="$this->getUpdateProfileFormActions()"
/>
</x-filament-panels::form>
<x-filament-panels::form wire:submit="updatePassword">
{{ $this->editPasswordForm }}
<x-filament-panels::form.actions
:actions="$this->getUpdatePasswordFormActions()"
/>
</x-filament-panels::form>
</x-filament-panels::page>
通过这种集成,表单不仅可见,而且还附有用于提交数据的功能操作按钮。 处理提交的数据
提交表单只是第一步。需要验证、处理数据,并可能存储数据。
php
class EditProfile extends Page implements HasForms
{
//...
public function updateProfile(): void
{
$data = $this->editProfileForm->getState();
$this->handleRecordUpdate($this->getUser(), $data);
$this->sendSuccessNotification();
}
public function updatePassword(): void
{
$data = $this->editPasswordForm->getState();
$this->handleRecordUpdate($this->getUser(), $data);
if (request()->hasSession() && array_key_exists('password', $data)) {
request()->session()->put(['password_hash_' . Filament::getAuthGuard() => $data['password']]);
}
$this->editPasswordForm->fill();
$this->sendSuccessNotification();
}
private function handleRecordUpdate(Model $record, array $data): Model
{
$record->update($data);
return $record;
}
}
updateProfile
和 updatePassword
方法管理每个表单的提交过程。
在密码更新的情况下,更新会话的 password_hash_
以防止意外的身份验证错误至关重要。
更新后,最好重置表单,确保后续条目的记录清晰可见。
提供反馈是用户体验不可或缺的一个方面。成功更新用户的个人资料或密码后,应通知用户。
私有函数 sendSuccessNotification():void
php
{
Notification::make()
->success()
->title(__('filament-panels::pages/auth/edit-profile.notifications.saved.title'))
->send();
}
实现现代表单样式
通过将 ->aside()
方法附加到表单的部分,您可以立即转换表单的外观。
类 EditProfile 扩展了 Page 实现 HasForms
php
{
// ...
public function editProfileForm(Form $form): Form
{
return $form
->schema([
Forms\Components\Section::make('Profile Information')
->aside() // This is the magic line!
->description('Update your account\'s profile information and email address.')
->schema([
// Your fields here...
]),
])
->model($this->getUser())
->statePath('profileData');
}
public function editPasswordForm(Form $form): Form
{
return $form
->schema([
Forms\Components\Section::make('Update Password')
->aside() // Again, for the modern touch!
->description('Ensure your account uses a long, random password for optimal security.')
->schema([
// Your fields here...
]),
])
->model($this->getUser())
->statePath('passwordData');
}
// Additional methods...
}
->aside()
方法有效地更改了表单部分的布局,将部分标题和描述移到一边(因此称为"aside"),并将实际的表单输入放在右侧。这导致了更紧凑、更现代的设计,既具有视觉吸引力又对用户友好。