statikbe / laravel-filament-flexible-content-blocks

The Laravel Filament Flexible Content Blocks package helps you to easily create content in Filament for any model, with predefined or custom blocks, and foreach block an extendable Blade view component.
MIT License
119 stars 19 forks source link

Can not use BlockSpatieMediaLibraryFileUpload with Repeater #52

Closed DanielSpravtsev closed 2 weeks ago

DanielSpravtsev commented 2 weeks ago

When implementing an image slider with a “Title - Image” format using Filament’s Repeater, the block_id is not set in the custom_properties.

In BlockSpatieMediaLibraryFileUpload’s -> setUp method:

$this->customProperties(function (Get $get) {
    return ['block' => $get(BlockIdField::FIELD)];
});

The block_id is not being assigned as expected.

sten commented 2 weeks ago

@DanielSpravtsev Can you send me the code of the form with the repeater?

DanielSpravtsev commented 2 weeks ago

@DanielSpravtsev Can you send me the code of the form with the repeater?

Sure, here’s the component code. I just started testing how to build my custom image component, so there’s a lot of extra code taken from existing components in an attempt to troubleshoot the issue.

It turns out that BlockSpatieMediaLibraryFileUpload can accept ->customProperties(), but how can I pass the necessary blockid to it?

class LinkSlider extends AbstractFilamentFlexibleContentBlock
{
    use HasImage;
    use HasImageConversionType;

    public static function getIcon(): string
    {
        return 'heroicon-o-cube';
    }

    protected static function makeFilamentSchema(): array|Closure
    {
        return [
            TextInput::make('header')
                ->required()
                ->label('Header'),
            Repeater::make('links')
                ->label('Links')
                ->addActionLabel('Add Link')
                ->schema([
                    TextInput::make('title')
                        ->required()
                        ->label('Title'),

                    BlockSpatieMediaLibraryFileUpload::make('image')
                        ->required()
                        ->collection(static::getName())
                        ->label('Image')
                        ->maxFiles(1),
                    TextInput::make('url')
                        ->url()
                        ->required()
                        ->label('Link'),
                ])
        ];
    }

    public static function addMediaCollectionAndConversion(HasMedia&HasMediaAttributes $record): void
    {
        $record->addMediaCollection(static::getName())
            ->registerMediaConversions(function (Media $media) use ($record) {
                static::addCropImageConversion($record, 1200, 630);
                static::addContainImageConversion($record, 1200, 630);

                // For Filament upload field
                $record->addFilamentThumbnailMediaConversion();
            });
    }

    public function getImageMedia(?string $conversion = null, array $attributes = []): ?HtmlableMedia
    {
        return $this->getHtmlableMedia($this->getBlockId(), '', '', $attributes);
    }

    public function getImageUrl(?string $conversion = null): ?string
    {
        dd($this->getImageMedia($this->getBlockId()));
    }

    public static function getLabel(): string
    {
        return 'Link block with images';
    }

    public static function getNameSuffix(): string
    {
        return 'link-slider';
    }

    public function render()
    {
        return view('blocks.link-slider');
    }
}
sten commented 2 weeks ago

@DanielSpravtsev Thanks!

I see two problems:

I hope this helps!

DanielSpravtsev commented 2 weeks ago

@DanielSpravtsev Thanks!

I see two problems:

  • You should extend from AbstractContentBlock instead of AbstractFilamentFlexibleContentBlock. The latter adds namespacing specifically for the package. Have a look at the comments on top of the AbstractFilamentFlexibleContentBlock implementation.
  • You should add BlockIdField::create(), to the schema of the repeater. Have a look at CardsBlock. Each repeater items needs a unique block id to map the images properly.

I hope this helps!

Thank you so much! This solved all the issues.

I replaced the extended class with AbstractContentBlock, and it requires implementing the getSearchableContent method.

Could you let me know where this method is used in Filament? Is it for global search or something else?

sten commented 2 weeks ago

It is used if you use Laravel Scout to search in your content, with for example a search index.