dewsign/nova-repeater-blocks

通过 Nova 资源上的多态关系启用可重复内容块。


README

通过 Nova 资源上的多态关系启用可重复内容块。

安装

通过 composer 安装重复块包

composer require dewsign/nova-repeater-blocks

运行迁移。注意:此包使用单个表来管理所有多态重复块,因此无需修改任何现有表!

php artisan migrate

Nova UI

对于本说明,我们将使用一个基本的博客示例,其中博客文章由多个富文本编辑器样式可重复内容块(例如文本、图片)生成。

首先将特性添加到您的模型中

// app/Post.php
use Dewsign\NovaRepeaterBlocks\Traits\HasRepeaterBlocks;

class Post extends Model {
    use HasRepeaterBlocks;
    ...
}

然后创建一个资源来定义此模型/资源的重复块(例如文章)。如果您计划在不同的模型上共享相同的块,则这可以更通用。扩展提供的基资源。

// app/Nova/PostRepeater.php

use App\Nova\RbText;
use Illuminate\Http\Request;
use Dewsign\NovaRepeaterBlocks\Fields\Repeater;

class PostRepeater extends Repeater
{
    // One or more Nova Resources which use this Repeater
    public static $morphTo = 'App\Nova\Post';

    // What type of repeater blocks should be made available
    public function types(Request $request)
    {
        return [
            RbText::class,
            RbImage::class,
        ];
    }
}

现在我们需要创建 RbTextRbImage,这两个都是具有额外特性的标准 Nova 资源。您可以根据需要命名它们,并像创建任何其他 Laravel 模型和资源一样简单地创建它们。

php artisan make:model -m RbText
// app/RbText.php
<?php
use Illuminate\Database\Eloquent\Model;
use Dewsign\NovaRepeaterBlocks\Traits\IsRepeaterBlock;

class RbText extends Model
{
    use IsRepeaterBlock;

    // Optional: To use a special template outside of the standard naming contention to render a block, define it here.
    public static $repeaterBlockViewTemplate = 'any.blade.view';
}
// app/Nova/RbText.php

use Dewsign\NovaRepeaterBlocks\Traits\IsRepeaterBlockResource;

class RbText extends Resource
{
    use IsRepeaterBlockResource;

    public function fields(Request $request)
    {
        return [
            Select::make('Format')->options([
                'p' => 'Paragraph',
                'h2' => 'Heading',
            ]),
            Text::make('Text'),
        ];
    }
    ...
}

最后,在您的 Nova 文章资源中创建关系。

// app/Nova/Post.php

class Post extends Resource
{
    public function fields(Request $request)
    {
        return [
            ...
            MorphMany::make(__('Repeaters'), 'repeaters', PostRepeater::class),
        ];
    }
}

前端 blade 输出

此包包含一个 blade 辅助函数,可在模型上渲染重复块。只需将整个模型传递给辅助函数即可按排序顺序渲染所有重复项。

@repeaterblocks($model)

// Optionally wrap each repeater with before and after code.
@repeaterblocks($model, '<div>', '</div>')

以下命名序列将用于查找正确的模板进行渲染。找到的第一个视图将被使用。命名空间是模型完整类命名空间的简化版本

    [
        $repeaterBlockViewTemplate,
        'repeaters.app.rbtext', // App\RbText
        'nova-repeater-blocks::app.rbtext',
        'repeaters.default',
        'nova-repeater-blocks::default',
    ]

重复块视图将接收以下参数

通常,在重复视图中访问数据的最简单方法是将属性直接作为变量访问。对于上面的示例,可以是。

// rbtext.blade.php

<{{ $format }}>
    {{ $text }}
</{{ $format }}>

还有一个用于 json 输出的辅助函数(对 JavaScript 前端很有用)。与之前一样,只需将模型传递进去即可生成 json 输出。

@repeaterjson($model)

定制

如果您想在重复块索引视图中显示其他字段,可以将计算属性合并到 fields 方法中。确保包括父字段。最好将自定义字段放在 fields 数组的前面。

// app/Nova/PostRepeater.php

public function fields(Request $request)
{
    return array_merge([
        Text::make('Format', function () {
            return $this->type->format;
        })->onlyOnIndex(),
    ], parent::fields($request))
}

注意: Laravel 2.0 引入了一个 reverse 元字段,当在重复项中使用 BelongsTo 字段时会导致错误。通常,您永远不会在嵌套重复项上有一个反向关系,因此我们通过使用 RepeatableBelongsTo 字段来避免这种情况。

有一个包含的 getExtraInfo() 函数,允许您在 Laravel Nova 管理 UI 中将任何信息传递到重复项索引视图中。

要传递数据到其中,请在您的重复资源上调用 getExtraInfo()

// app/Repeaters/Common/Blocks/SampleRepeaterBlock.php

    public function getExtraInfo()
    {
        return $this->template;
    }

自定义视图块

自定义视图块允许您将 HTML 视图模板用作重复块。要使用此块,您创建的自定义模板必须存储在 repeater-blocks 配置文件中定义的路径。默认情况下,自定义模板的路径为 resources/views/repeaters/custom

一旦创建了自己的自定义视图,它们将在选择“自定义视图”重复类型时出现在“模板名称”下拉列表中。

容器

所有默认块都可以容器化。基本上是将多个重复块分组在容器中的方法。您可以通过在 resources/views/vendor/nova-repeater-blocks/container 目录中创建新的模板来创建新的容器类型。这些将自动出现在选择选项中。

您可以通过将 CanBeContainerised 特性添加到模型,以及将 ResourceCanBeContainerised 添加到块资源,来允许自定义重复块容器化。

图片

样式

您可以通过向 /views/vendor/nova-repeater-blocks/common/image 资源文件夹中添加新模板来创建多个图片样式。如果找不到视图,系统将回退到默认样式。

图片处理

配置提供了一个轻松定制图片处理器的途径。创建一个具有兼容的获取方法的新类,该方法可以返回处理后的图片 URL。每个项模板都可以有一个独特的图片处理器。包含了一些常见的模板名称,但它们都渲染默认模板(通常与图片处理器结合使用就足够了)。

以下是一个自定义图片处理器的示例,用于替换默认设置

namespace App\Processors;

use Illuminate\Support\Facades\Storage;
use Dewsign\NovaRepeaterBlocks\Processors\ImageProcessor;

class DefaultImageProcessor extends ImageProcessor
{
    public static function get(string $image, array $params = [])
    {
        // Process the image and perform any special tasks before returning the final Image URL.

        return $myImageURL;
    }

    public static function delete(string $image)
    {
        // Handle the deletion of the image (e.g. from a remote filesystem)
    }
}

现在,您可以将此处理器分配给 repeater-blocks 配置中的任何默认(和自定义)图片样式。

return [
    ...
    'images' => [
        ...
        'processors' => [
            'default' => App\Processors\DefaultImageProcessor::class,
        ],
    ],
    ...
];

在您的视图中,在重复块中,您可以使用 default_image 辅助函数,或者您可以直接使用 ImageProcessors 来处理任何图片,通过调用 DefaultImageProcessor::get('path/to/image')

高级嵌套重复块

如果需要,任何重复块都可以包含更多的嵌套重复块。为了实现这一点,重复块模型必须有一个 types 方法,指示可以添加到块中的类型。这些类型中的每一个都必须包含一个 sourceTypes 方法,您应该能够简单地引用父块的 types

class GridBlock extends Model
{
    use IsRepeaterBlock;
    use HasRepeaterBlocks;

    public static $repeaterBlockViewTemplate = 'repeaters.grid';

    public static function types()
    {
        return [
            \App\Nova\GridBlockItem::class,
        ];
    }
}
class GridBlockItem extends Model
{
    use IsRepeaterBlock;

    public static $repeaterBlockViewTemplate = 'repeaters.gridItem';

    public static function sourceTypes()
    {
        return GridBlock::types();
    }
}

多态关系冗余

在删除多态记录时,如果所有记录表的数据尚未删除。现在,您可以向 repeater-blocks 配置文件分配额外的配置,以对形态表采取行动,尝试防止记录在显示多态列表时导致非渲染或破坏网站。这允许记录优雅地失败,并保持任何附加数据完整性,而不是硬性/强制删除失败的记录。

  • 要启用现有安装,您只需将以下代码包含到已发布的 repeater-blocks 配置文件中。
return [
    ...
    'morph_tables' => [
        'my_morph_table_name' => [
            'disable_columns' => [
                'enabled' => false
            ]
        ],
    ],
    ...
];
  • 将配置更新以符合您的需求,就像更新 my_morph_table_name 到您的形态表名称一样简单,并在 disable_columns 中添加一个键值对列表,其中键是您在形态表中的表列,值是您希望更新该列的值。除了 disable_columns 键值对之外,您还可以包括多个要检查的形态表。配置将仅使用给定形态表名称中的 disable_columns,如果它是问题原因。
return [
    ...
    'morph_tables' => [
        'repeaters' => [
            'disable_columns' => [
                'enabled' => false,
            ]
        ],
        'spaces' => [
            'disable_columns' => [
                'active' => false,
                'content' => "Issue rendering this block"
            ]
        ],
    ],
    ...
];