cactus-galaxy / filament-astrotomic
Astrotomic's Laravel Translatable 包的 Filament 支持。
Requires
- php: ^8.1
- astrotomic/laravel-translatable: ^11.12
- filament/filament: ^3.0
- laravel/framework: ^10.0 || ^11.0
- spatie/laravel-package-tools: ^1.15.0
Requires (Dev)
- laravel/pint: ^1.0
- nunomaduro/collision: ^7.9
- orchestra/testbench: ^8.0 || ^9.0
- pestphp/pest: ^2.0
- pestphp/pest-plugin-arch: ^2.0
- pestphp/pest-plugin-laravel: ^2.0
This package is auto-updated.
Last update: 2024-09-09 00:31:22 UTC
README
此包是 Filament 和 laravel-translatable 的扩展。
受 spatie/laravel-translatable 的启发,为您的 Laravel 应用程序提供另一种翻译包的替代方案。
在 GalaxyStore 中查看 Filament 控面板的更多配置示例 - 一个包含 Filament、Astrotomic 包和其他内容的演示项目。
安装
您可以通过 Composer 安装此包
composer require cactus-galaxy/filament-astrotomic
发布 astrotomic/laravel-translatable
包的配置
php artisan vendor:publish --tag="translatable"
之后,您将需要配置应用程序应使用的区域设置。
'locales' => [ 'uk', 'en', ],
将插件添加到面板
要将插件添加到面板,您必须使用 plugins()
方法在配置文件中包含它
use CactusGalaxy\FilamentAstrotomic\FilamentAstrotomicTranslatablePlugin; public function panel(Panel $panel): Panel { return $panel // ... ->plugins([ FilamentAstrotomicTranslatablePlugin::make(), ]); }
准备您的模型类
您需要使您的模型可翻译。您可以在 Laravel 可翻译文档 中阅读如何操作。
准备您的资源类
您必须将 ResourceTranslatable
特性应用到您的资源类中
use CactusGalaxy\FilamentAstrotomic\Resources\Concerns\ResourceTranslatable; use Filament\Resources\Resource; class ProductResource extends Resource { use ResourceTranslatable; // ... }
使资源页面可翻译
在 准备您的资源类 之后,您还必须使每个资源页面的可翻译性。您可以在每个资源文件夹的 Pages
目录中找到您的资源页面。要准备一个页面,您必须将相应的 {Type}Translatable
特性应用到它上
use CactusGalaxy\FilamentAstrotomic\Resources\Pages\Record\ListTranslatable; use Filament\Resources\Pages\ListRecords; class ListProducts extends ListRecords { use ListTranslatable; // ... }
use CactusGalaxy\FilamentAstrotomic\Resources\Pages\Record\CreateTranslatable; use Filament\Resources\Pages\CreateRecord; class CreateProduct extends CreateRecord { use CreateTranslatable; // ... }
use CactusGalaxy\FilamentAstrotomic\Resources\Pages\Record\EditTranslatable; use Filament\Resources\Pages\EditRecord; class EditProduct extends EditRecord { use EditTranslatable; // ... }
如果您有资源的 ViewRecord
页面
use CactusGalaxy\FilamentAstrotomic\Resources\Pages\Record\ViewTranslatable; use Filament\Resources\Pages\ViewRecord; class ViewProduct extends ViewRecord { use ViewTranslatable; // ... }
为特定资源设置可翻译的区域设置
默认情况下,使用 Astrotomic 的 Locales 辅助方法 all()
加载可翻译的区域设置,该方法返回 translatable.locales
配置中的所有区域设置。作为替代方案,您可以通过在资源类中覆盖 getTranslatableLocales()
方法来自定义特定资源的可翻译区域设置
use CactusGalaxy\FilamentAstrotomic\Resources\Concerns\ResourceTranslatable; use Filament\Resources\Resource; class ProductResource extends Resource { use ResourceTranslatable; // ... public static function getTranslatableLocales(): array { return ['uk', 'en']; } }
在表单上使用区域设置标签
TranslatableTabs
扩展了默认的 Filament\Forms\Components\Tabs
组件,并提供了一种为每个区域设置创建标签式标签的方法。在 localeTabSchema
方法中,您可以定义每个标签的架构回调。此回调将为每个区域设置调用以生成标签架构。
localeTabSchema
支持 实用工具注入
要接受 TranslatableTab
实例作为参数以获取当前区域设置,您需要将参数命名为 $translatableTab
或使用类型提示,如下面的示例所示。
以下是如何在 ProductResource
表单中使用 TranslatableTabs
的示例
use CactusGalaxy\FilamentAstrotomic\Forms\Components\TranslatableTabs; use CactusGalaxy\FilamentAstrotomic\Resources\Concerns\ResourceTranslatable; use CactusGalaxy\FilamentAstrotomic\TranslatableTab; use Filament\Forms\Form; use Filament\Resources\Resource; class ProductResource extends Resource { use ResourceTranslatable; // ... public static function form(Form $form): Form { return $form->columns(1)->schema([ Forms\Components\TextInput::make('slug') ->unique(ignoreRecord: true) ->required() ->readOnly() ->helperText('Генерується автоматично при зміні назви') ->maxLength(255), TranslatableTabs::make() ->localeTabSchema(fn (TranslatableTab $tab) => [ Forms\Components\TextInput::make($tab->makeName('name')) // required only for the main locale ->required($tab->isMainLocale()) ->maxLength(255) // generate slug for the item based on the main locale ->live(onBlur: true) ->afterStateUpdated(function (Forms\Set $set, Forms\Get $get, $state) use ($tab) { if ($tab->isMainLocale()) { $set('slug', Str::slug($state)); } }), ]), // ... ]); } // ... }
使用此代码,您将为每个区域设置获得带有 name
字段的标签。在标签中 name
字段将仅对 主区域设置 必需。它还将根据主区域设置生成项目的 slug。
默认情况下,$tab->makeName('name')
使用数组语法命名 - {$locale}.{$name}
,但您可以通过在 TranslatableTabs
上调用 makeNameUsing
来更改它,例如,使用 纯语法
TranslatableTabs::make() // plain syntax ->makeNameUsing(fn (string $name, string $locale) => "{$name}:{$locale}") // or use an alias ->makeNameUsingPlainSyntax() // ..
预加或后加标签页
有时您需要在本地化标签页之前或之后添加标签页。您可以使用 prependTabs
和 appendTabs
方法来实现这一点
use Filament\Forms\Components\Tabs\Tab; TranslatableTabs::make() ->localeTabSchema(fn (TranslatableTab $tab) => [ // ... ]) ->prependTabs([ Tab::make('Tab before localized') ->schema([ // ... ]) // ... ]) ->appendTabs(fn () => [ // you also can pass a callback or array Tab::make('Tab after localized') ->schema([ // ... ]) // ... ])
处理带翻译的模态表单
如果您想在模态表单中使用翻译,您需要做一些更改,以正确修改并填充您的表单。
编辑表格操作
例如,我们有一个 ProductResource
,但没有编辑页面。
为了在编辑操作模态中处理翻译,您需要覆盖资源类中 EditAction
类的 mutateRecordDataUsing
方法。
如果您的 Column 路径为 translation.*
,确保在返回之前从记录数据中取消设置 translation
关系,否则记录数据将保存不正确。
use App\Models\Product; use CactusGalaxy\FilamentAstrotomic\Forms\Components\TranslatableTabs; use CactusGalaxy\FilamentAstrotomic\Resources\Concerns\ResourceTranslatable; use Filament\Forms\Form; use Filament\Tables; use Filament\Tables\Table; class ProductResource extends Resource { use ResourceTranslatable; // ... public static function form(Form $form): Form { // ... form with `TranslatableTabs` } public static function table(Table $table): Table { return $table ->columns([ Tables\Columns\TextColumn::make('translation.name'), // ... ]) // ... ->actions([ Tables\Actions\EditAction::make()->mutateRecordDataUsing(function (Product $record, array $data) { return self::mutateTranslatableData($record, $data); })->mutateFormDataUsing(function (Product $record, array $data) { $record->unsetRelation('translation'); return $data; }), // ... ]); } public static function getPages(): array { return [ 'index' => Pages\ListProducts::route('/'), // edit route is missing ]; }
选择带有模态选项
有一个更复杂的例子,使用了 Select
组件。例如,我们需要为产品管理(创建或编辑)一个类别。
在定义了可翻译字段的 CategoryResource
形式中。
use CactusGalaxy\FilamentAstrotomic\Forms\Components\TranslatableTabs; use CactusGalaxy\FilamentAstrotomic\Resources\Concerns\ResourceTranslatable; use CactusGalaxy\FilamentAstrotomic\TranslatableTab; use Filament\Forms; use Filament\Forms\Form; class CategoryResource extends Resource { use ResourceTranslatable; // ... public static function form(Form $form): Form { return $form ->schema([ TranslatableTabs::make() ->localeTabSchema(fn (TranslatableTab $tab) => [ Forms\Components\TextInput::make($tab->makeName('name')) ->required($tab->isMainLocale()) ->maxLength(255), ]), ]); } // ... }
然后是 ProductResource
,我们可以使用带有模态选项的 Select
组件。请注意,我们需要调用 fillEditOptionActionFormUsing
方法并修改记录数据
use App\Models\Category; use Filament\Forms; use Filament\Forms\For; Forms\Components\Select::make('category_id') ->required() ->native(false) ->searchable() ->options( Category::query() ->joinTranslations() ->pluck('name', 'categories.id') ->toArray() ) // Configure create action - https://filamentphp.com/docs/3.x/forms/fields/select#creating-a-new-option-in-a-modal ->createOptionModalHeading('Create') ->createOptionForm(fn (Form $form) => CategoryResource::form($form)) ->createOptionUsing(function (array $data) { $optionRecord = Category::create($data); return $optionRecord->id; }) // Configure edit action - https://filamentphp.com/docs/3.x/forms/fields/select#editing-the-selected-option-in-a-modal ->editOptionModalHeading('Edit') ->editOptionForm(fn (Form $form) => CategoryResource::form($form)) ->fillEditOptionActionFormUsing(function (string $state) { if (!$state) { return []; } $optionRecord = Category::find($state); return CategoryResource::mutateTranslatableData($record, $record->attributesToArray()); }) ->updateOptionUsing(function (array $data, string $state) { $optionRecord = Category::find($state); $optionRecord->update($data); return $optionRecord->id; })
在列表中为可翻译模型设置列
Filament 默认支持列的嵌套,这意味着您可以在列路径中使用 .
来访问嵌套属性,您不需要为可翻译模型设置特殊列。
Tables\Columns\TextColumn::make('translation.name'),
但是,对可翻译列进行搜索对于每个文本列来说更复杂。为了解决和添加通过列进行搜索的选项,我们建议将以下行添加到您的 ServiceProvider 中的 boot 方法以配置您的列。
来自 GalaxyStore 的
GalaxyStore
use Astrotomic\Translatable\Translatable; use Astrotomic\Translatable\Contracts\Translatable as TranslatableContract; use Filament\Tables\Columns\TextColumn; use Filament\Tables\Table; use Illuminate\Database\Eloquent\Builder; // in `boot` method TextColumn::configureUsing(function (TextColumn $column): void { // match `translations.title` or `translation.title` if (Str::match('@^translations?\.(\w+)$@', $column->getName())) { $column ->searchable(query: function (Builder $query, string $search) use ($column): Builder { $columnName = Str::after($column->getName(), '.'); if ($query->hasNamedScope('whereTranslationLike')) { /* @var Translatable|TranslatableContract $query */ return $query->whereTranslationLike($columnName, "%{$search}%"); } return $query->where($columnName, 'like', "%{$search}%"); }); } });
也许在某个功能中,有人会为此创建一个列,但当前您可以使用此代码来配置您的列。
测试
composer test
变更日志
有关最近更改的更多信息,请参阅 CHANGELOG
贡献
有关详细信息,请参阅 CONTRIBUTING
快速示例,您可以克隆 GalaxyStore 和此包到一个文件夹
Projects
|-FilamentAstrotomic
|-GalaxyStore
将 repositories
部分添加到您的 GalaxyStore/composer.json
文件
{ "repositories": [ { "type": "path", "url": "../FilamentAstrotomic", "options": { "symlink": true } } ] }
然后执行 composer
composer require "cactus-galaxy/filament-astrotomic:@dev"
或手动将包添加到 composer.json
文件
{ "require": { "cactus-galaxy/filament-astrotomic": "@dev" } }
安全漏洞
有关如何报告安全漏洞的更多信息,请参阅我们的 安全策略
致谢
许可
MIT 许可证 (MIT)。有关更多信息,请参阅 许可文件