
一个简单而完整的 Laravel Nova 灵活字段(Flexible Field),非常适合重复且灵活的分组字段。

这是一份非常精简的指南,可帮助您尽快上手。 完整文档请参阅 https://whitecube.github.io/nova-flexible-content
composer require whitecube/nova-flexible-content
灵活字段(Flexible Field)可以轻松管理可重复、可排序的字段组。与 Laravel Nova 现有的少数解决方案不同,它不会限制您在这些组中可以使用哪些字段。这意味着您可以使用所有 Laravel Nova 字段类型,以及任何社区开发的字段。
布局(Layout)代表可在 Flexible 字段内重复的一组字段。您可以根据需要添加任意数量的布局。如果只定义一个布局,该字段将表现得像一个简单的 Repeater;添加更多布局后,您将获得 Flexible Content。这两个概念都类似于 Wordpress ACF 插件中的对应功能。
可以通过 Flexible 字段上的以下方法添加布局:
addLayout(string $title, string $name, array $fields)
$name 参数用于在字段值中存储所选择的布局。请谨慎选择,因为您很可能需要用它来识别应用程序中的布局。
use Whitecube\NovaFlexibleContent\Flexible;
/**
* Get the fields displayed by the resource.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function fields(Request $request)
{
return [
// ...
Flexible::make('Content')
->addLayout('Simple content section', 'wysiwyg', [
Text::make('Title'),
Markdown::make('Content')
])
->addLayout('Video section', 'video', [
Text::make('Title'),
Image::make('Video Thumbnail', 'thumbnail'),
Text::make('Video ID (YouTube)', 'video'),
Text::make('Video Caption', 'caption')
])
];
}

您可以像这样更改默认的“Add layout”按钮文本:
Flexible::make('Content')
->button('Add something amazing!');

如果您使用的是 Laravel 6 或更低版本,或者不想使用 cast,请在模型上结合 HasFlexible trait 使用访问器。
Laravel 7 引入了自定义 cast,而 flexible content 字段正是它们的理想用例。该字段将其值存储为单个 JSON 字符串,这意味着该字符串需要先解析才能在应用程序中使用。使用本包中的 FlexibleCast 类即可轻松完成:
namespace App;
use Illuminate\Database\Eloquent\Model;
use Whitecube\NovaFlexibleContent\Value\FlexibleCast;
class MyModel extends Model
{
protected $casts = [
'flexible-content' => FlexibleCast::class
];
}
默认情况下,FlexibleCast 类会收集基本的 Layout 实例。如果您想将布局映射为自定义 Layout 实例,也是可以的。首先,运行 php artisan flexible:cast MyFlexibleCast 创建自定义 flexible cast。这将在 App\Casts 目录中创建文件。
然后轻松地将自定义布局类映射到对应的键:
namespace App\Casts;
class MyFlexibleCast extends FlexibleCast
{
protected $layouts = [
'wysiwyg' => \App\Nova\Flexible\Layouts\WysiwygLayout::class,
'video' => \App\Nova\Flexible\Layouts\VideoLayout::class,
]
}
如果您需要更多控制,也可以覆盖 getLayoutMappings 方法。
由 FlexibleCast cast 和 HasFlexible trait 返回的集合扩展了原始的 Illuminate\Support\Collection。这些自定义布局集合暴露了一个 find(string $name) 方法,该方法返回具有给定布局 $name 的第一个布局。
布局有点像 伪模型。它们使用 Laravel 的 HasAttributes trait,这意味着您可以为布局的属性定义访问器与修改器。此外,还可以使用以下方法访问 Layout 的属性:
name()返回布局的名称。
title()返回布局的标题(在 Nova 中显示的名称)。
key()返回布局的唯一键(布局的唯一标识符)。
在使用 Flexible Content 字段时,您很快就会遇到一些上述基础内容无法满足的用例。因此,我们以可扩展的方式开发了这个包,使您可以轻松地为 Field 及其输出添加自定义行为和/或功能。
有时,addLayout 定义可能会变得很长,或者您可能希望它们能与其他 Flexible 字段共享。解决办法是将 Layout 提取到自己的类中。有关详细信息,请参阅文档。
除了可复用的 Layout 类之外,您还可以更进一步,为 Flexible 字段创建 Preset 类。这使您可以在任何地方复用整个 Flexible 字段,也让 Flexible 字段更容易实现动态化,例如按条件添加 Layout。最后但同样重要的是,如果您的 Flexible 字段包含大量 addLayout 定义,它们还能帮助清理您的 Nova Resource 类。有关详细信息,请参阅文档。
默认情况下,该字段利用模型表上的 JSON 列。在某些情况下,您确实想使用此字段,但出于某种原因,JSON 属性不是合适的方式。例如,您可能希望将值存储到另一个表中(这意味着您将使用 Flexible Content 字段,而不是传统的 BelongsToMany 或 HasMany 字段)。别担心,我们已经为您考虑到了!
通过创建自己的 Resolver 类来告诉字段如何存储和检索其内容,该类基本上只包含两个简单方法:get 和 set。有关详细信息,请参阅文档。
您可能听说过我们的另一个包 nova-page,它是一个 Nova 工具,允许编辑静态页面,例如 "About" 页面(或类似页面),而无需单独为其声明模型。通常情况下,Flexible Content 字段会派上用场。别担心,这两个包可以很好地协同工作!首先创建一个 nova page 模板,然后将 flexible content 添加到模板的字段中。
如文档所述,您可以在 Blade 视图中使用 {{ Page::get('attribute') }} 访问 nova-page 的静态内容。像这样请求 flexible content 时,它会返回描述 flexible content 的原始 JSON 字符串,这当然不是很有用。相反,您只需在页面模板中实现 Whitecube\NovaFlexibleContent\Concerns\HasFlexible trait,它就会暴露 Page::flexible('attribute') 门面方法,并负责 flexible content 的转换。
namespace App\Nova\Templates;
// ...
use Whitecube\NovaFlexibleContent\Concerns\HasFlexible;
class Home extends Template
{
use HasFlexible;
// ...
}
如果您在生产应用程序中使用此包,请考虑赞助我们!这是帮助我们继续做我们热爱之事的最佳方式:打造出色的开源软件。
欢迎自由地提出修改建议、请求新功能,或自行修复 bug。我们相信仍然有很多可以改进的地方,也非常乐意合并有用的拉取请求。
谢谢!
在添加新功能或修复 bug 时,请添加相应的单元测试。当前的测试集有限,但每增加一个单元测试都会提高包的质量。
通过运行 composer test 来执行 PHPUnit。
在 Whitecube,我们将大量开源软件应用于日常工作中。因此,当有机会回馈时,我们感到非常兴奋!
我们希望您会喜欢我们的这份小小贡献。如果您在项目中发现它有用,我们很乐意收到您的来信。在 Twitter 上关注我们,获取更多更新!