Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Filament Image Gallery Laravel Package

al-saloul/filament-image-gallery

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require al-saloul/filament-image-gallery
    

    Publish the config (if needed):

    php artisan vendor:publish --provider="AlSaloul\FilamentImageGallery\FilamentImageGalleryServiceProvider"
    
  2. Register the Plugin Add to app/Providers/Filament/AdminPanelProvider.php:

    public function panel(Panel $panel): Panel
    {
        return $panel
            ->plugins([
                \AlSaloul\FilamentImageGallery\FilamentImageGalleryPlugin::make(),
            ]);
    }
    
  3. First Use Case: Table Column

    use AlSaloul\FilamentImageGallery\Columns\ImageGalleryColumn;
    
    ImageGalleryColumn::make('images')
        ->images(fn ($record) => $record->images) // Array of image URLs
        ->thumbnailWidth(100) // Optional: Set thumbnail dimensions
        ->thumbnailHeight(100);
    
  4. First Use Case: Infolist Entry

    use AlSaloul\FilamentImageGallery\Widgets\ImageGalleryWidget;
    
    ImageGalleryWidget::make('images')
        ->images(fn ($record) => $record->images)
        ->columns(3); // Optional: Set columns for thumbnail grid
    

Implementation Patterns

Common Workflows

1. Dynamic Image Sources

Leverage closures for dynamic image paths:

ImageGalleryColumn::make('gallery')
    ->images(fn ($record) => [
        Storage::disk('public')->url($record->image1),
        Storage::disk('public')->url($record->image2),
    ]);

2. Customizing Viewer Behavior

Configure Viewer.js options via config (config/filament-image-gallery.php):

'viewer_options' => [
    'zoomRatio' => 0.5, // Default zoom increment
    'button' => true,   // Show/hide buttons
    'toolbar' => true,  // Show/hide toolbar
],

3. Integration with Filament Forms

Use in Custom Fields for uploads:

use AlSaloul\FilamentImageGallery\Fields\ImageGalleryField;

ImageGalleryField::make('gallery')
    ->images(fn ($record) => $record->images)
    ->addAction(
        Action::make('edit')
            ->action(fn ($record) => $this->edit($record))
    ),

4. Lazy Loading & Performance

  • Preload Thumbnails: Cache thumbnails in booted() method:
    public function booted()
    {
        Cache::remember('image-gallery-thumbs', now()->addHours(1), function () {
            return Image::whereIn('id', [1, 2, 3])->get()->pluck('thumbnail_path');
        });
    }
    
  • Use loading="lazy" in blade templates if extending manually.

5. Localization & Accessibility

Override default labels in config:

'translations' => [
    'zoom_in' => __('Zoom In'),
    'zoom_out' => __('Zoom Out'),
    'rotate_left' => __('Rotate Left'),
    'rotate_right' => __('Rotate Right'),
],

Integration Tips

With Spatie Media Library

ImageGalleryColumn::make('media')
    ->images(fn ($record) => $record->getMedia('images')->pluck('full_url')),

With Livewire Components

Pass data via props:

public $images = [];

public function mount()
{
    $this->images = $record->images->pluck('url')->toArray();
}

Then render the gallery in Blade:

<x-filament-image-gallery :images="$images" />

Custom Styling

Override CSS via resources/css/filament-image-gallery.css:

.viewerjs {
    --thumbnail-width: 120px;
    --thumbnail-height: 120px;
}

Gotchas and Tips

Pitfalls

1. Image Paths Must Be Absolute URLs

  • Fails: Relative paths (/storage/image.jpg) or missing http://.
  • Works: Full URLs (https://example.com/storage/image.jpg) or Laravel’s Storage::url().

2. CORS Issues with Local Development

  • If images are hosted locally (e.g., http://localhost), ensure:
    • Your dev server allows CORS headers.
    • Use http:// (not https://) for local URLs to avoid mixed-content warnings.

3. Thumbnail Dimensions Not Respected

  • Cause: Viewer.js ignores thumbnailWidth/Height if images aren’t pre-processed.
  • Fix: Use Laravel’s Image facade to generate thumbnails:
    $thumbs = $record->images->map(fn ($image) => Image::make($image)->resize(100, 100)->path());
    

4. Plugin Not Registering

  • Check:
    • Panel provider is updated (AdminPanelProvider).
    • Plugin is listed in ->plugins([]).
    • No PHP errors in storage/logs/laravel.log.

5. Conflicts with Other Viewer Libraries

  • If using Lightbox or Fancybox, ensure no duplicate JS/CSS conflicts:
    // In a custom JS file, initialize Viewer.js only once:
    document.addEventListener('DOMContentLoaded', function() {
        new Viewer(document.getElementById('gallery'), {
            // Options here
        });
    });
    

Debugging Tips

1. Verify Viewer.js Initialization

Inspect the rendered HTML for:

<div id="gallery" class="viewerjs"></div>

Check browser console for errors like:

Uncaught ReferenceError: Viewer is not defined

Fix: Ensure viewer.js is loaded (check public/vendor/filament-image-gallery/).

2. Log Image URLs

Debug dynamic image sources:

->images(fn ($record) => {
    \Log::debug('Gallery images:', $record->images->toArray());
    return $record->images->pluck('url');
}),

3. Disable Cache During Development

Clear Filament cache:

php artisan filament:cache:clear

4. Override Viewer.js Options

Force options via JavaScript:

document.addEventListener('filament-image-gallery-ready', function(e) {
    e.detail.viewer.options.zoomRatio = 0.25;
});

Extension Points

1. Custom Buttons

Extend Viewer.js toolbar:

// In a custom JS file:
document.addEventListener('filament-image-gallery-ready', function(e) {
    e.detail.viewer.toolbar.addButton({
        id: 'custom-button',
        text: 'Custom Action',
        action: () => alert('Custom action triggered!')
    });
});

2. Server-Side Image Processing

Hook into ImageGalleryColumn to process images before display:

use AlSaloul\FilamentImageGallery\Columns\ImageGalleryColumn;

ImageGalleryColumn::make('processed_gallery')
    ->images(fn ($record) => {
        return $record->images->map(function ($image) {
            return Image::make($image->path)
                ->resize(800, 600)
                ->encode()
                ->path;
        });
    }),

3. Custom Storage Adapter

For non-public storage (e.g., S3 private files), use signed URLs:

->images(fn ($record) => $record->images->map(fn ($image) =>
    Storage::disk('s3')->temporaryUrl(
        $image->path,
        now()->addMinutes(30),
        ['ResponseContentDisposition' => 'inline']
    )
)),

4. Event Listeners

Listen for gallery interactions:

// In a service provider:
event(new FilamentImageGalleryEvent($images, $record));

(Note: Requires extending the package or using JavaScript events.)


5. Localization

Extend translations in resources/lang/en/filament-image-gallery.php:

return [
    'zoom_in' => 'Ampliar',
    'zoom_out' => 'Reducir',
    // ... other keys
];
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
directorytree/privacy-filter-classifier
directorytree/privacy-filter
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi
splash/scopes
splash/toolkit
testo/output-teamcity
testo/bridge-symfony
spatie/flare-daemon-runtime