Weave 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

Thumbnail Bundle Laravel Package

genj/thumbnail-bundle

genj/thumbnail-bundle provides configurable thumbnail generation for Symfony applications, helping you create, cache, and serve resized images through services, Twig helpers, and flexible size definitions.

View on GitHub
Deep Wiki
Context7

Getting Started

Be clear about what you are installing: genj/thumbnail-bundle is a Symfony bundle, not a Laravel package. It wraps liip/imagine-bundle and changes the URL/filename that Liip produces so the generated thumbnail carries a keyword-bearing name (e.g. my-photo-small.jpg) instead of Liip's default cache path (/media/cache/small/uploads/my-photo.jpg). If you are on Laravel, you cannot composer require it and call it a day — you either run it inside a Symfony app that fronts your media, or (more likely) you read its naming logic and reimplement the ~50 lines in Laravel.

Where to look first in the repo:

  1. composer.json — confirms the Symfony/Liip version constraints (this is a 2015-era package, so expect Symfony 2.x and PHP 5.x constraints that will not resolve on a modern stack).
  2. DependencyInjection/ and Resources/config/services.yml — shows the service that wraps Liip's cache manager and how the Twig helper is registered.
  3. The Twig extension / helper — this is the public surface you will actually call (thumbnail(path, filter) or similar).
  4. The class that builds the SEO filename — this is the only piece worth porting to Laravel.

Minimal install (Symfony only):

composer require genj/thumbnail-bundle
// app/AppKernel.php
new Genj\ThumbnailBundle\GenjThumbnailBundle(),
new Liip\ImagineBundle\LiipImagineBundle(),

Configure at least one Liip filter, then call the bundle's helper with an image path and that filter name to get a friendly URL.

First use case: an article/listing page with a cover_image column. You want <img src="/media/cache/small/uploads/2015/12/my-photo-small.jpg"> rather than the default cache URL — the filter name and original slug live in the filename, which is the whole point of the package.

Implementation Patterns

1. Controller/service usage (Symfony). Inject the bundle's thumbnail service and generate URLs in your controller or a view model, keeping templates dumb:

$url = $this->get('genj.thumbnail')->getUrl($entity->getImagePath(), 'small');

2. Twig helper. The bundle ships a Twig function; the day-to-day pattern is:

<img src="{{ thumbnail(article.coverImage, 'small') }}" alt="{{ article.title }}">

3. The Laravel port (what you will actually do). Since the package is archived and Symfony-shaped, extract the naming convention into a small service and pair it with intervention/image or spatie/laravel-image:

class SeoThumbnail
{
    public function url(string $path, string $filter): string
    {
        $name = pathinfo($path, PATHINFO_FILENAME);
        $ext  = pathinfo($path, PATHINFO_EXTENSION);
        $slug = Str::slug($name);

        return "/media/cache/{$filter}/{$slug}-{$filter}.{$ext}";
    }
}

Then register a Blade directive or a Storage macro so views stay clean: @thumb($article->cover_image, 'small').

4. Pair with srcset/responsive images. The naming scheme really pays off when you emit several filters for one source:

<img
  src="{{ thumb($post->image, 'medium') }}"
  srcset="{{ thumb($post->image, 'small') }} 480w,
          {{ thumb($post->image, 'medium') }} 960w,
          {{ thumb($post->image, 'large') }} 1600w"
  sizes="(max-width: 600px) 480px, 960px"
  alt="{{ $post->title }}">

5. Integration tips.

  • Generate the URL at render time, but cache the string per (image, filter) pair — regeneration is cheap once the file exists on disk.
  • Invalidate on re-upload: changing the source filename naturally changes the SEO name, so old cached files become orphaned. Add a cleanup job keyed by the source path.
  • Keep the SEO segment derived from the slug, not the raw filename, so spaces/unicode never reach the URL.

Gotchas and Tips

  • Archived, zero stars, last release 2015-12-24. Treat it as reference code, not a dependency. Its composer.json constraints almost certainly conflict with PHP 8 / Symfony 5+; a composer require will fail or force you into dependency-hell workarounds.
  • Symfony-only by construction. It hooks into Liip's cache manager and Symfony's DI container. There is no Laravel service provider. Do not attempt to shoehorn it in; port the filename logic instead (~a single class) and use Laravel's own image pipeline.
  • Filename collisions are the main correctness risk. Two different source directories can share a basename (uploads/a/photo.jpg and uploads/b/photo.jpg), producing the same friendly output when you flatten to photo-small.jpg. Append a short hash of the full source path, and only strip it for display if you truly need clean names.
  • The web server must be able to resolve the friendly URL. Liip generates into /media/cache/<filter>/.... If your new name changes that structure, you need either a rewrite that maps friendly names back to the Liip cache layout, or you generate-on-demand in a controller/route. Forgetting this yields 404s for every thumbnail.
  • Path traversal and sanitization. Any scheme that interpolates user-controlled filenames into a filesystem path must run through basename() + slugification; never trust the raw value from a DB row or upload.
  • Debugging checklist: confirm the Liip filter exists (liip_imagine.filter_sets), confirm the cache directory is writable, run Liip's cache resolve command (e.g. liip:imagine:cache:resolve) to materialize files, and clear both Symfony's cache and the Liip media cache after config changes — stale config is the most common "my URL is wrong" cause.
  • Extension points (if you do fork it): the naming strategy is the seam worth decorating — subclass or replace the filename generator so you can inject your own slug/hash policy without touching the Twig helper.
  • Bottom line for a Laravel team: budget an afternoon to copy the naming idea, not an afternoon fighting the bundle. The value here is the convention (keywords in the thumbnail filename for SEO and readable URLs), and that is trivially reproducible with Str::slug() plus your image driver.
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.
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route