Files
laralog/app/Filament/Resources/Posts/Schemas/PostForm.php
T
goukiandCursor f81397a289 feat: use xpier media library for uploads and markdown embeds
Store media:ID in post bodies instead of CDN URLs, and keep sablog attach tokens as a fallback.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 19:03:52 +00:00

134 lines
6.2 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Filament\Resources\Posts\Schemas;
use App\Blog\Support\MarkdownMediaEmbed;
use Filament\Actions\Action;
use Filament\Forms\Components\DateTimePicker;
use Filament\Forms\Components\MarkdownEditor;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\Toggle;
use Filament\Notifications\Notification;
use Filament\Schemas\Components\Actions;
use Filament\Schemas\Components\Utilities\Get;
use Filament\Schemas\Components\Utilities\Set;
use Filament\Schemas\Schema;
use Xpier\FilamentMediaLibrary\Components\MediaPicker;
use Xpier\FilamentMediaLibrary\Models\MediaLibrary;
class PostForm
{
public static function configure(Schema $schema): Schema
{
return $schema
->components([
\Filament\Schemas\Components\Section::make('内容')
->columns(2)
->schema([
TextInput::make('title')
->label('标题')
->required()
->columnSpanFull(),
TextInput::make('slug')
->label('Slug(留空自动生成)'),
Select::make('category_id')
->label('分类')
->relationship('category', 'name'),
Select::make('content_format')
->label('内容格式')
->options([
'markdown' => 'Markdown',
'html' => 'HTML',
])
->default('markdown')
->live(),
Select::make('status')
->label('状态')
->options([
'published' => '已发布',
'draft' => '草稿',
'private' => '私密',
])
->default('published'),
MarkdownEditor::make('content')
->label('正文')
->required()
->helperText('Markdown 插入图片用 ![说明](media:ID),文件用 [文件名](media:ID)。不要把 CDN / 对象存储地址写进正文。')
->fileAttachments(false)
->columnSpanFull(),
MediaPicker::make('insert_media_id')
->label('从媒体库插入正文')
->module('articles')
->mediaType(null)
->dehydrated(false)
->helperText('选好媒体后点「插入到正文」。Markdown 写入 media:ID 引用,渲染时再换成真实地址。')
->columnSpanFull(),
Actions::make([
Action::make('insertSelectedMedia')
->label('插入到正文')
->action(function (Get $get, Set $set): void {
$mediaId = $get('insert_media_id');
$media = is_numeric($mediaId)
? MediaLibrary::query()->find((int) $mediaId)
: null;
if (! $media instanceof MediaLibrary) {
Notification::make()->title('请先从媒体库选择文件')->warning()->send();
return;
}
$snippet = app(MarkdownMediaEmbed::class)->snippet(
$media,
(string) ($get('content_format') ?: 'markdown')
);
$set('content', rtrim((string) $get('content'))."\n\n".$snippet."\n");
$set('insert_media_id', null);
Notification::make()->title('已写入正文引用')->success()->send();
}),
])->columnSpanFull(),
]),
\Filament\Schemas\Components\Section::make('封面与摘要')
->columns(2)
->schema([
MediaPicker::make('cover_media_id')
->label('封面图')
->module('articles')
->mediaType('image')
->relationship('coverMedia')
->columnSpanFull(),
Textarea::make('excerpt')
->label('摘要(留空自动截取)')
->rows(3),
TextInput::make('keywords')
->label('关键词(逗号分隔)'),
]),
\Filament\Schemas\Components\Section::make('发布设置')
->columns(3)
->schema([
DateTimePicker::make('published_at')
->label('发布时间')
->default(now()),
Toggle::make('is_sticky')
->label('置顶'),
Toggle::make('close_comment')
->label('关闭评论'),
TextInput::make('read_password')
->label('阅读密码(留空公开)'),
TextInput::make('views')
->label('浏览量')
->numeric()
->disabled(),
TextInput::make('comment_count')
->label('评论数')
->numeric()
->disabled(),
]),
]);
}
}