guava / filament-nested-resources
Requires
- filament/filament: ^3.0.0
- livewire/livewire: ^3.0
- spatie/laravel-package-tools: ^1.15
Requires (Dev)
- filament/spatie-laravel-translatable-plugin: ^3.2
- laravel/pint: ^1.11
- orchestra/testbench: ^8.0
- dev-main
- dev-beta
- dev-alpha
- 1.x-dev
- 1.2.0
- 1.1.0
- 1.0.1
- 1.0.0
- 1.0.0-beta.5
- 1.0.0-beta.4
- 1.0.0-beta.3
- 1.0.0-beta.2
- 1.0.0-beta.1
- 1.0.0-alpha.11
- 1.0.0-alpha.10
- 1.0.0-alpha.9
- 1.0.0-alpha.8
- 1.0.0-alpha.7
- 1.0.0-alpha.6
- 1.0.0-alpha.5
- 1.0.0-alpha.4
- 1.0.0-alpha.3
- 1.0.0-alpha.2
- 1.0.0-alpha.1
- dev-fix/page-actions
- dev-fix/camel-case-helpers
- dev-fix/route-names
- dev-develop
This package is auto-updated.
Last update: 2024-08-27 07:07:58 UTC
README
Filament Nested Resources
Filament Nested Resources 允许您创建任何深度的嵌套资源。这对于过于复杂而无法使用关系管理器,但又不能作为独立资源的资源非常有用。
首次公开发布在这里。
展示
支持我们
您的支持对我们插件持续进步至关重要。我们感谢每一位至今为止为我们旅程做出贡献的用户。
虽然我们的插件对所有用户都开放,但如果您将其用于商业目的,并认为它为您的事业增添了显著价值,我们恳请您考虑通过GitHub Sponsors支持我们。这种赞助将帮助我们持续开发和维护,以保持我们的插件强大且更新。您提供的任何金额都将极大地帮助我们实现目标。加入我们,让这个插件变得更好,推动进一步的创新。
安装
您可以通过composer安装此包
composer require guava/filament-nested-resources
使用方法
在文档中,我引用了root
嵌套资源和child
嵌套资源。唯一的区别是,Root
是关系树中的第一个资源。
在示例中:ArtistResource > AlbumResource > SongResource
Artist 将是根资源,其他则是子资源。
支持的关系
目前我们只支持一对一和多态一对一关系。
演示项目
为了更好地了解嵌套资源的工作原理以及解决您可能遇到的问题,我们创建了一个演示 Laravel 项目:[https://github.com/GuavaCZ/filament-nested-resources-demo](https://github.com/GuavaCZ/filament-nested-resources-demo)
快速入门
为了设置嵌套资源,您需要执行以下步骤
- 在您想要嵌套的资源(根和所有子资源)上,添加
NestedResource
特性。您将需要实现getAncestor
方法。对于根资源,返回null
,对于所有子资源,根据以下文档实现。 - 在第一步中资源的每一页上,添加
NestedPage
特性。 - 创建一个
RelationManager
([Filament 文档](https://filamentphp.com/docs/3.x/panels/resources/relation-managers#creating-a-relation-manager))或一个RelationPage
([Filament 文档](https://filamentphp.com/docs/3.x/panels/resources/relation-managers#relation-pages)),将资源绑定在一起。将NestedRelationManager
特性添加到其中任何一个。
让我们假设展示截图中的场景,我们有以下模式
- Artist 模型。
- Album 模型(属于 Artist)。
- Song 模型(属于 Album)。
首先我们创建 ArtistResource
use Filament\Resources\Resource; use Guava\FilamentNestedResources\Concerns\NestedResource; class ArtistResource extends Resource { use NestedResource; // If using Relation Manager: public static function getRelations(): array { return [ AlbumsRelationManager::class, ]; } public static function getPages(): array { return [ 'index' => Pages\ListArtists::route('/'), 'create' => Pages\CreateArtist::route('/create'), 'edit' => Pages\EditArtist::route('/{record}/edit'), 'view' => Pages\ViewArtist::route('/{record}'), // In case of relation page. // Make sure the name corresponds to the name of your actual relationship on the model. 'albums' => Pages\ManageArtistAlbums::route('/{record}/albums'), // Needed to create child records // The name should be '{relationshipName}.create': 'albums.create' => Pages\CreateArtistAlbum::route('/{record}/albums/create'), ]; } public static function getAncestor(): ?Ancestor { return null; } }
接下来,我们创建 AlbumResource
use Filament\Resources\Resource; use Guava\FilamentNestedResources\Concerns\NestedResource; class AlbumResource extends Resource { use NestedResource; public static function getRelations(): array { return [ // Repeat the same for Song Resource ]; } public static function getAncestor() : ?Ancestor { // Configure the ancestor (parent) relationship here return Ancestor::make( 'albums', // Relationship name 'artist', // Inverse relationship name ); } }
在 ArtistResource
和 AlbumResource
的每一页上,我们添加 NestedPage
特性
use Filament\Resources\Pages\CreateRecord; use Guava\FilamentNestedResources\Concerns\NestedPage; class CreateArtist extends CreateRecord { use NestedPage; // }
use Filament\Resources\Pages\EditRecord; use Guava\FilamentNestedResources\Concerns\NestedPage; class EditArtist extends EditRecord { use NestedPage; // }
use Filament\Resources\Pages\ListRecords; use Guava\FilamentNestedResources\Concerns\NestedPage; class ListArtists extends ListRecords { use NestedPage; // }
现在让我们创建一个新页面,该页面将用于创建子记录。让我们在 ArtistResource/Pages
中创建 CreateArtistAlbum
页面
use Guava\FilamentNestedResources\Pages\CreateRelatedRecord; use Guava\FilamentNestedResources\Concerns\NestedPage; class CreateArtistAlbum extends CreateRelatedRecord { use NestedPage; // This page also needs to know the ancestor relationship used (just like relation managers): protected static string $relationship = 'albums'; // We can usually guess the nested resource, but if your app has multiple resources for this // model, you will need to explicitly define it // public static string $nestedResource = AlbumResource::class; }
别忘了在 getPages
方法中注册页面。
最后,我们创建 AlbumsRelationManager
或如果您更愿意使用关系页面,则创建 ManageArtistAlbums
页面。我们只需要在这里添加 NestedRelationManager
特性。
对于 RelationManager
use Filament\Resources\RelationManagers\RelationManager; use Guava\FilamentNestedResources\Concerns\NestedRelationManager; class AlbumsRelationManager extends RelationManager { use NestedRelationManager; // We can usually guess the nested resource, but if your app has multiple resources for this // model, you will need to explicitly define the it // public static string $nestedResource = AlbumResource::class; }
对于 RelationPage
use Filament\Resources\Pages\ManageRelatedRecords; use Guava\FilamentNestedResources\Concerns\NestedPage; use Guava\FilamentNestedResources\Concerns\NestedRelationManager; class ManageArtistAlbums extends ManageRelatedRecords { use NestedPage; // Since this is a standalone page, we also need this trait use NestedRelationManager; // }
可选,我们建议删除子资源 NestedResources
(在本例中为 AlbumResource)中的 index
和 create
页面。
自定义面包屑
每个资源都可以控制自己部分的面包屑,默认由一个 index
面包屑和一个 detail
面包屑组成。
index
面包屑通常重定向到索引页面。
detail
面包屑通常重定向到详情(编辑或查看)页面,默认情况下将显示记录的路线键(ID,如果没有进行其他配置)。
您可以通过 NestedResource
的 getBreadcrumbRecordLabel
方法重写标签。
public static function getBreadcrumbRecordLabel(Model $record) { return $record->first_name . ' ' . $record->last_name; }
或者您可以通过在资源上重写 getBreadcrumbs
方法完全重写资源的面包屑部分。
public static function getBreadcrumbs(Model $record, string $operation): array { return [ 'my-custom-url' => 'My custom label', ]; }
贡献
请参阅 CONTRIBUTING 了解详细信息。
安全漏洞
请查看 我们的安全策略 了解如何报告安全漏洞。
致谢
许可证
MIT 许可证 (MIT)。请参阅 许可证文件 获取更多信息。