awcodes / filament-curator
FilamentPHP 的媒体选择插件。
Requires
- php: ^8.1
- intervention/image: ^2.7
- league/glide-symfony: ^2.0
- spatie/laravel-package-tools: ^1.13.5
Requires (Dev)
- awcodes/filament-tiptap-editor: ^3.0
- filament/filament: ^3.0
- laravel/pint: ^1.0
- nunomaduro/collision: ^7.0
- orchestra/testbench: ^8.0
- pestphp/pest: ^2.19
- pestphp/pest-plugin-laravel: ^2.2
- pestphp/pest-plugin-livewire: ^2.1
- spatie/laravel-ray: ^1.26
- 4.x-dev
- 3.x-dev
- v3.6.9
- v3.6.8
- v3.6.7
- v3.6.6
- v3.6.5
- v3.6.4
- v3.6.3
- v3.6.2
- v3.6.1
- v3.6.0
- v3.5.8
- v3.5.7
- v3.5.6
- v3.5.5
- v3.5.4
- v3.5.3
- v3.5.2
- v3.5.1
- v3.5.0
- v3.4.12
- v3.4.11
- v3.4.10
- v3.4.9
- v3.4.8
- v3.4.7
- v3.4.6
- v3.4.5
- v3.4.4
- v3.4.3
- v3.4.2
- v3.4.1
- v3.4.0
- v3.3.1
- v3.3.0
- v3.2.6
- v3.2.5
- v3.2.4
- v3.2.3
- v3.2.2
- v3.2.1
- v3.2.0
- v3.1.6
- v3.1.5
- v3.1.4
- v3.1.3
- v3.1.2
- v3.1.1
- v3.1.0
- v3.0.7
- v3.0.6
- v3.0.5
- v3.0.4
- v3.0.3
- v3.0.2
- v3.0.1
- v3.0.0
- v3.0.0-beta.12
- v3.0.0-beta.11
- v3.0.0-beta.10
- v3.0.0-beta.9
- v3.0.0-beta.8
- v3.0.0-beta7
- v3.0.0-beta.6
- v3.0.0-beta.5
- v3.0.0-beta.4
- v3.0.0-beta.3
- v3.0.0-beta.2
- v3.0.0-beta.1
- v3.0.0-alpha1
- 2.x-dev
- v2.10.3
- v2.10.2
- v2.10.1
- v2.10.0
- v2.9.1
- v2.9.0
- v2.8.9
- v2.8.8
- v2.8.7
- v2.8.6
- v2.8.5
- v2.8.4
- v2.8.3
- v2.8.2
- v2.8.1
- v2.8.0
- v2.7.7
- v2.7.6
- v2.7.5
- v2.7.4
- v2.7.3
- v2.7.2
- v2.7.1
- v2.7.0
- v2.6.5
- v2.6.4
- v2.6.3
- v2.6.2
- v2.6.1
- v2.6.0
- v2.5.11
- v2.5.10
- v2.5.9
- v2.5.8
- v2.5.7
- v2.5.6
- v2.5.5
- v2.5.4
- v2.5.3
- v2.5.2
- v2.5.1
- v2.5.0
- v2.4.3
- v2.4.2
- v2.4.1
- v2.4.0
- v2.3.1
- v2.3.0
- v2.2.9
- v2.2.8
- v2.2.7
- v2.2.6
- v2.2.5
- v2.2.4
- v2.2.3
- v2.2.2
- v2.2.1
- v2.2.0
- v2.1.3
- v2.1.2
- v2.1.1
- v2.1.0
- v2.0.15
- v2.0.14
- v2.0.13
- v2.0.12
- v2.0.11
- v2.0.10
- v2.0.9
- v2.0.8
- v2.0.7
- v2.0.6
- v2.0.5
- v2.0.4
- v2.0.3
- v2.0.2
- v2.0.1
- v2.0.0
- 1.x-dev
- v1.1.8
- v1.1.7
- v1.1.6
- v1.1.5
- v1.1.4
- v1.1.3
- v1.1.2
- v1.1.1
- v1.1.0
- v1.0.3
- v1.0.2
- v1.0.1
- v1.0.0
- v0.7.7
- v0.7.6
- v0.7.5
- v0.7.4
- v0.7.3
- v0.7.2
- v0.7.1
- v0.7.0
- v0.6.2
- v0.6.1
- v0.6.0
- v0.5.0
- v0.4.6
- v0.4.5
- v0.4.4
- v0.4.3
- v0.4.2
- v0.4.1
- v0.4.0
- v0.3.4
- v0.3.3
- v0.3.2
- v0.3.1
- v0.3.0
- v0.2.9
- v0.2.8
- v0.2.7
- v0.2.6
- v0.2.5
- v0.2.4
- v0.2.3
- v0.2.2
- v0.2.1
- v0.2.0
- v0.1.1
- v0.1.0
- v0.0.1-alpha
- dev-revert-523-3.x
This package is auto-updated.
Last update: 2024-08-24 17:01:45 UTC
README
Filament Admin 的媒体选择/管理插件。
注意 此包与 Spatie Media Library 不兼容。
安装
您可以通过 composer 安装此包,然后运行安装命令
composer require awcodes/filament-curator
php artisan curator:install
如果您使用的是独立表单包,则需要在布局文件中包含 Curator 模态框,通常您会将其放置在关闭 body
标签之前。
<x-curator::modals.modal />
为了与 Filament 的主题化方法保持一致,您需要使用自定义主题来使用此插件。
注意 如果您尚未设置自定义主题并且正在使用面板,请首先遵循 Filament 文档 中的说明。以下适用于面板包和独立表单包。
您还需要添加 cropper.js。
npm install -D cropperjs
- 将插件样式表和 cropperjs 样式表导入您的主题 css 文件。
@import '<path-to-node-modules>/cropperjs/dist/cropper.css'; @import '<path-to-vendor>/awcodes/filament-curator/resources/css/plugin.css';
- 将插件的视图添加到您的
tailwind.config.js
文件。
content: [ './vendor/awcodes/filament-curator/resources/**/*.blade.php', ]
升级
如果您是从 2.x 升级到 3.x,则需要运行以下操作
php artisan curator:upgrade
这将更新 Curator 的数据库模式并创建一个备份您的媒体表,在升级后可以选择删除。
附加步骤
使用方法
全局设置
全局设置可以通过插件的配置文件进行管理。您可以使用以下命令发布配置文件
php artisan vendor:publish --tag="curator-config"
与 Filament 面板一起使用
如果您使用 Filament 面板,则需要将插件添加到面板的配置中。这将注册插件的资源到面板。所有方法都是可选的,如果没有提供,将从中读取配置文件。
public function panel(Panel $panel): Panel { return $panel ->plugins([ \Awcodes\Curator\CuratorPlugin::make() ->label('Media') ->pluralLabel('Media') ->navigationIcon('heroicon-o-photo') ->navigationGroup('Content') ->navigationSort(3) ->navigationCountBadge() ->registerNavigation(false) ->defaultListView('grid' || 'list') ->resource(\App\Filament\Resources\CustomMediaResource::class) ]); }
Curator 选择字段
将 CuratorPicker 字段包含在您的表单中,以触发模态框,并选择现有图像或上传新图像。可以采用 Filament 的 FileUpload
组件的一些常用方法来帮助对每个 CuratorPicker 的特定实例进行尺寸、验证等。
use Awcodes\Curator\Components\Forms\CuratorPicker; CuratorPicker::make(string $fieldName) ->label(string $customLabel) ->buttonLabel(string | Htmlable | Closure $buttonLabel) ->color('primary|secondary|success|danger') // defaults to primary ->outlined(true|false) // defaults to true ->size('sm|md|lg') // defaults to md ->constrained(true|false) // defaults to false (forces image to fit inside the preview area) ->pathGenerator(DatePathGenerator::class|UserPathGenerator::class) // see path generators below ->lazyLoad(bool | Closure $condition) // defaults to true ->listDisplay(bool | Closure $condition) // defaults to true ->tenantAware(bool | Closure $condition) // defaults to true ->defaultPanelSort(string | Closure $direction) // defaults to 'desc' // see https://filamentphp.com/docs/2.x/forms/fields#file-upload for more information about the following methods ->preserveFilenames() ->maxWidth() ->minSize() ->maxSize() ->rules() ->acceptedFileTypes() ->disk() ->visibility() ->directory() ->imageCropAspectRatio() ->imageResizeTargetWidth() ->imageResizeTargetHeight() ->multiple() // required if using a relationship with multiple media ->relationship(string $relationshipName, string 'titleColumnName') ->orderColumn('order') // only necessary to rename the order column if using a relationship with multiple media
关系
单个
表单组件
CuratorPicker::make('featured_image_id') ->relationship('featured_image', 'id'),
模型
use Awcodes\Curator\Models\Media; public function featuredImage(): BelongsTo { return $this->belongsTo(Media::class, 'featured_image_id', 'id'); }
多个
表单组件
CuratorPicker::make('product_picture_ids') ->multiple() ->relationship('product_pictures', 'id') ->orderColumn('order'), // only necessary if you need to rename the order column
模型
use Awcodes\Curator\Models\Media; public function productPictures(): BelongsToMany { return $this ->belongsToMany(Media::class, 'media_post', 'post_id', 'media_id') ->withPivot('order') ->orderBy('order'); }
可变形
注意: 当前实现支持表单中的可变形关系,但在表格列中尚未启用。需要进一步的调整以实现完全兼容。
示例迁移
Schema::create('media_items', function (Blueprint $table) { $table->id(); $table->morphs('mediable'); $table->foreignId('media_id')->constrained()->onDelete('cascade'); $table->integer('order'); $table->string('type'); $table->timestamps(); });
模型
public function media(): MorphMany { return $this->morphMany(MediaItem::class, 'mediable')->orderBy('order'); }
表单组件
CuratorPicker::make('document_ids') ->multiple() ->relationship('media', 'id') ->orderColumn('order') // Optional: Rename the order column if needed ->typeColumn('type') // Optional: Rename the type column if needed ->typeValue('document'); // Optional: Specify the type value if using types
路径生成
默认情况下,Curator 将使用配置中设置的目录和磁盘来存储您的媒体。如果您想以不同的方式存储媒体,Curator 提供了路径生成器,可以修改其行为。只需在配置中全局设置或为您的 CuratorPicker
字段实例设置您想要的即可。
use Awcodes\Curator\View\Components\CuratorPicker; use Awcodes\Curator\PathGenerators\DatePathGenerator; public function register() { CuratorPicker::make('image') ->pathGenerator(DatePathGenerator::class); }
可用生成器
DefaultPathGenerator
将文件保存在磁盘/目录中。
DatePathGenerator
将文件保存在磁盘/目录/Y/m/d 中。
UserPathGenerator
将文件保存在磁盘/目录/user-auth-identifier 中
您也可以通过在自己的类中实现PathGenerator
接口来自由地使用自己的路径生成器。
use Awcodes\Curator\PathGenerators; class CustomPathGenerator implements PathGenerator { public function getPath(?string $baseDir = null): string { return ($baseDir ? $baseDir . '/' : '') . 'my/custom/path'; } }
Curator列
为了在表格中渲染您的媒体,Curator提供了一个具有与Filament的ImageColumn相同方法的CuratorColumn
。
CuratorColumn::make('featured_image') ->size(40)
对于多张图片,您可以控制显示的图片数量、环大小和重叠。
CuratorColumn::make('product_pictures') ->ring(2) // options 0,1,2,4 ->overlap(4) // options 0,2,3,4 ->limit(3),
关系
如果您使用关系来存储您的媒体,则会在列上遇到n+1问题。为了防止这种情况,您应该修改您的表查询以预加载关系。
例如,当在您的ListResource中使用管理面板时
protected function getTableQuery(): Builder { return parent::getTableQuery()->with(['featured_image', 'product_pictures']); }
Curations
Curations是一种创建图像自定义大小和焦点的途径。
Curation预设
如果您经常使用某个curations,您可以创建预设,这些预设将在curations模态中可用,以便更容易地重复使用。创建curations预设后,可以通过其键引用它们以在blade文件中输出。
use Awcodes\Curator\Curations\CurationPreset; class ThumbnailPreset extends CurationPreset { public function getKey(): string { return 'thumbnail'; } public function getLabel(): string { return 'Thumbnail'; } public function getWidth(): int { return 200; } public function getHeight(): int { return 200; } public function getFormat(): string { return 'webp'; } public function getQuality(): int { return 60; } }
然后简单地在配置中注册您的预设。
'curation_presets' => [ ThumbnailPreset::class, ],
您还可以通过在配置文件中更改curation_formats
来更改curations可用的格式。这些应该与Intervention Image的编码类型兼容。
'curation_formats' => [ 'jpg', 'jpeg', 'webp', 'png', 'avif', ],
如果您想禁用媒体编辑器中的“Curations”标签,可以在配置文件中将tabs.display_curation
设置为false
。默认值为true
。
'tabs' => [ 'display_curation' => false, ],
如果您想禁用媒体编辑器中的“上传新”标签,可以在配置文件中将tabs.display_upload_new
设置为false
。默认值为true
。
'tabs' => [ 'display_upload_new' => false, ],
Glider Blade组件
为了尽可能简化媒体输出,Curator提供了一个<x-curator-glider>
blade组件。
有关Glide选项的更多信息,请参阅Glide的快速参考。
特殊属性
- media: id(整数)或模型(Media)实例 必需
- loading: 默认为'lazy'
- glide: 如果不想使用单个属性,可以使用此参数传递Glide查询字符串
- srcset: 这将输出glide生成的URL的必要srcset。必须是一个包含srcset宽度的数组,并且需要设置'sizes'属性。
- force: (布尔值)此参数可用于强制glider返回签名URL,这在从云盘中返回URL时很有用。这应该在了解可能具有性能影响的情况下使用。
<div class="w-64 aspect-video"> <x-curator-glider class="object-cover w-auto" :media="1" glide="" fallback="" :srcset="['1024w','640w']" sizes="(max-width: 1200px) 100vw, 1024px" background="" blur="" border="" brightness="" contrast="" crop="" device-pixel-ratio="" filter="" fit="" flip="" format="" gamma="" height="" quality="" orientation="" pixelate="" sharpen="" width="" watermark-path="" watermark-width="" watermark-height="" watermark-x-offset="" watermark-y-offset="" watermark-padding="" watermark-position="" watermark-alpha="" /> </div>
Glider回退图片
Glide允许使用回退图片,如果媒体项不存在。可以通过传递一个引用您的注册GliderFallback
之一的fallback
属性来设置它。
use Awcodes\Curator\Glide\GliderFallback; class MyCustomGliderFallback extends GliderFallback { public function getAlt(): string { return 'boring fallback image'; } public function getHeight(): int { return 640; } public function getKey(): string { return 'card_fallback'; } public function getSource(): string { return 'https://via.placeholder.com/640x420.jpg'; } public function getType(): string { return 'image/jpg'; } public function getWidth(): int { return 420; } }
然后请在配置中注册您的回退。
'glide' => [ 'fallbacks' => [ MyCustomGliderFallback::class, ], ],
然后您可以在blade组件中引用您的回退。
<x-curator-glider :media="1" fallback="card_fallback"/>
自定义Glide路由
默认情况下,Curator将在通过Glide提供图像时使用curator
路由。如果您想更改此设置,可以更新Curator配置文件中的glide.route_path
设置。
'glide' => [ 'route_path' => 'uploads', ],
自定义Glide服务器
如果您想使用自己的Glide服务器来处理Glide处理的媒体,您可以在自己的类中实现ServerFactory
接口并将其设置为配置。
use League\Glide\Responses\LaravelResponseFactory; use League\Glide\Server; use League\Glide\ServerFactory; class CustomServerFactory implements Contracts\ServerFactory { public function getFactory(): ServerFactory | Server { return ServerFactory::create([ 'driver' => 'imagick', 'response' => new LaravelResponseFactory(app('request')), 'source' => storage_path('app'), 'source_path_prefix' => 'public', 'cache' => storage_path('app'), 'cache_path_prefix' => '.cache', 'max_image_size' => 2000 * 2000, ]); } }
然后请在配置中注册您的服务器。
'glide' => [ 'server' => \App\Glide\CustomServerFactory::class, ],
Curation Blade组件
为了尽可能简化curations的输出,Curator提供了一个<x-curator-curation>
blade组件。
特殊属性
- media: id(整数)或模型(Media)实例 必需
<x-curator-curation :media="10" curation="thumbnail" loading="lazy"/>
实际用例
由于curations可能对每个媒体项都存在,或者不存在,因此最好在blade文件中使用回退到glider组件,以确保始终适当地渲染图像。这也让您不必为每个媒体项创建curations,只需为那些您试图更改焦点等的媒体项创建。
@php $preset = new ThumbnailPreset(); @endphp @if ($media->hasCuration('thumbnail')) <x-curator-curation :media="$media" curation="thumbnail"/> @else <x-curator-glider class="object-cover w-auto" :media="$media" :width="$preset->getWidth()" :height="$preset->getHeight()" /> @endif
自定义模型
如果您想使用自己的模型来处理媒体,可以通过扩展 Curator 的 Media
模型来实现,并将其设置到配置文件中。
use Awcodes\Curator\Models\Media; class CustomMedia extends Media { protected $table = 'media'; }
'model' => \App\Models\Cms\Media::class,
测试
composer test
变更日志
请参阅 变更日志 了解最近的变化信息。
贡献
请参阅 贡献指南 了解详细信息。
安全漏洞
请查看 我们的安全策略 了解如何报告安全漏洞。
致谢
- Adam Weston
- The PHP League 提供了出色的 Glide 包。
- Cropperjs 提供了他们令人惊叹的 JavaScript 包。
- 所有贡献者
许可证
MIT 许可证 (MIT)。请参阅 许可证文件 了解更多信息。