Xây dựng nhanh Admin Panel với FilamentPHP

· 5 min read

Filament đã cách mạng hóa cách chúng ta xây dựng giao diện quản trị trong Laravel. Được xây dựng trên TALL stack (Tailwind, Alpine, Laravel, Livewire), nó mang lại trải nghiệm phát triển tuyệt vời để tạo ra các admin panel đẹp, responsive.

Cài đặt

composer require filament/filament:"^3.2" -W
php artisan filament:install --panels

Lệnh này tạo một user mới và thiết lập admin panel tại /admin.

Tạo Resource

Resource là cốt lõi của Filament. Chúng ánh xạ tới các Eloquent models của bạn.

php artisan make:filament-resource Post

Lệnh này tạo ra:

  • app/Filament/Resources/PostResource.php
  • app/Filament/Resources/PostResource/Pages/ListPosts.php
  • app/Filament/Resources/PostResource/Pages/CreatePost.php
  • app/Filament/Resources/PostResource/Pages/EditPost.php

Cấu hình Form

Định nghĩa các trường nhập liệu trong form():

use Filament\Forms;
use Filament\Forms\Form;

public static function form(Form $form): Form
{
    return $form
        ->schema([
            Forms\Components\TextInput::make('title')
                ->required()
                ->maxLength(255),
            
            Forms\Components\Str::make('slug')
                ->required(),

            Forms\Components\Select::make('author_id')
                ->relationship('author', 'name')
                ->searchable()
                ->preload(),

            Forms\Components\RichEditor::make('content')
                ->columnSpanFull(),
            
            Forms\Components\Toggle::make('is_published'),
            
            Forms\Components\DateTimePicker::make('published_at'),
        ]);
}

Cấu hình Table

Định nghĩa bảng dữ liệu trong table():

use Filament\Tables;
use Filament\Tables\Table;

public static function table(Table $table): Table
{
    return $table
        ->columns([
            Tables\Columns\TextColumn::make('title')
                ->searchable()
                ->sortable(),
            
            Tables\Columns\TextColumn::make('author.name')
                ->label('Tác giả')
                ->sortable(),

            Tables\Columns\IconColumn::make('is_published')
                ->boolean(),

            Tables\Columns\TextColumn::make('created_at')
                ->dateTime()
                ->sortable(),
        ])
        ->filters([
            Tables\Filters\SelectFilter::make('author')
                ->relationship('author', 'name'),
                
            Tables\Filters\TernaryFilter::make('is_published'),
        ])
        ->actions([
            Tables\Actions\EditAction::make(),
            Tables\Actions\DeleteAction::make(),
        ])
        ->bulkActions([
            Tables\Actions\BulkActionGroup::make([
                Tables\Actions\DeleteBulkAction::make(),
            ]),
        ]);
}

Relationships

Filament xử lý các mối quan hệ rất thanh lịch.

BelongsTo

Sử dụng trong form qua component Select và trong table qua dot notation author.name.

HasMany (Relation Managers)

Để quản lý comments trên một bài viết, tạo một relation manager:

php artisan make:filament-relation-manager PostResource comments title

Đăng ký nó trong PostResource:

public static function getRelations(): array
{
    return [
        RelationManagers\CommentsRelationManager::class,
    ];
}

Widget Tùy chỉnh

Tạo dashboard thống kê:

php artisan make:filament-widget BlogStatsOverview --stats-overview
// app/Filament/Widgets/BlogStatsOverview.php
protected function getStats(): array
{
    return [
        Stat::make('Tổng bài viết', Post::count()),
        Stat::make('Đã xuất bản', Post::where('is_published', true)->count()),
        Stat::make('Chờ duyệt', Post::where('is_published', false)->count()),
    ];
}

Actions

Custom actions cho phép bạn thực thi logic trực tiếp từ table hoặc form.

Tables\Actions\Action::make('publish')
    ->action(function (Post $record) {
        $record->update(['is_published' => true]);
    })
    ->requiresConfirmation()
    ->color('success')
    ->icon('heroicon-o-check');

Kích hoạt tìm kiếm toàn cục cho resource của bạn:

protected static ?string $recordTitleAttribute = 'title';

public static function getGlobalSearchResultDetails(Model $record): array
{
    return [
        'Author' => $record->author->name,
    ];
}

Validations & Hooks

Bạn có thể hook vào vòng đời của các trang resource.

// app/Filament/Resources/PostResource/Pages/CreatePost.php

protected function mutateFormDataBeforeCreate(array $data): array
{
    $data['user_id'] = auth()->id();
    return $data;
}

protected function afterCreate(): void
{
    // Gửi thông báo
}

Tùy chỉnh Giao diện

Tùy chỉnh màu sắc, logo và các cài đặt đơn giản:

// app/Providers/Filament/AdminPanelProvider.php
public function panel(Panel $panel): Panel
{
    return $panel
        ->default()
        ->id('admin')
        ->path('admin')
        ->colors([
            'primary' => Color::Amber,
        ])
        ->brandLogo(asset('images/logo.png'));
}

Best Practices

  1. Giữ logic trong Models - Đừng làm phình to Resources với business logic
  2. Sử dụng Policies - Filament tuân thủ standard Laravel policies cho authorization
  3. Tối ưu Queries - Sử dụng eagerLoad trong table queries để tránh lỗi N+1
  4. Custom Fields - Tạo custom blade components cho các input đặc biệt
  5. Testing - Sử dụng Livewire testing helpers để test tương tác

Tóm tắt

Filament loại bỏ sự nhàm chán khi xây dựng admin panels. Nó cho phép bạn:

  • Tạo giao diện CRUD ngay lập tức
  • Quản lý các mối quan hệ phức tạp dễ dàng
  • Tạo custom dashboards và widgets
  • Mở rộng chức năng với TALL stack

Đây hiện là lựa chọn tốt nhất cho các giao diện quản trị Laravel.

Bình luận