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

File Widget Laravel Package

friendsofvictoire/file-widget

A file management widget for Laravel that adds upload, browse, and preview controls to your admin panels or dashboards. Drop it into a view, point it at a disk, and manage files without building custom UI.

View on GitHub
Deep Wiki
Context7

Getting Started

Reality check first: this is not a Laravel package. friendsofvictoire/file-widget is a Symfony bundle built for Victoire DCMS (a Symfony 2.x–era CMS). There is no service provider, no config/file-widget.php, no Blade views, no Eloquent model, no facade. Composer will happily autoload its classes into a Laravel app, but they reference the Symfony HTTP kernel, Twig, Doctrine, and Victoire's widget base classes — nothing boots without that stack.

Where to look first (in the repo, in this order):

  1. composer.json — the version constraints tell you the era (expect symfony/* ~2.7|~2.8, php >=5.5, a dependency on victoire/widget-bundle).
  2. WidgetFileBundle.php — the DI extension; almost certainly trivial (services, maybe a form type registration).
  3. Entity/WidgetFile.php — the actual data model: typically a title, a file reference owned by Victoire's media manager, and maybe a label.
  4. Form/WidgetFileType.php — the editor-facing UX; this is where the file picker integration lives.
  5. Resources/views/WidgetFile/{edit,show}.html.twig — the real contract. The templates reveal which entity fields actually exist.

First use case if you genuinely run Victoire: composer require friendsofvictoire/file-widget, register the bundle in AppKernel.php after the Victoire bundles, clear the cache, open a page in the Victoire editor, drop the "File" widget into a slot, pick a file from the media manager, publish. That's the whole feature: an editor-inserted downloadable file link.

First use case in Laravel: there isn't one. The only honest starting point is to read the entity + templates as a spec and rebuild it natively (see below).

Implementation Patterns

Patterns the bundle itself follows (relevant if you maintain the host Symfony app):

  • Slot-based rendering. Editors drag the widget into a page slot; the render pipeline instantiates the stored widget entity and renders show.html.twig with it. Your job is markup, not orchestration.
  • Template override over forking. Copy Resources/views/WidgetFile/show.html.twig into app/Resources/WidgetFileBundle/views/WidgetFile/show.html.twig to change output. This is the intended extension point and it keeps you off a fork.
  • Reference, don't own, the file. The widget stores a pointer into Victoire's media manager; the physical file, its public path, and its lifecycle belong to the media bundle. Preserve that separation if you extend anything.
  • Extend the form type, not the widget name. Add fields (description, button label, target="_blank") via a form type extension or subclass. Changing the widget's registered name breaks every existing page.

The Laravel translation you'd actually ship in a day:

// migration
Schema::create('widgets', function (Blueprint $t) {
    $t->id();
    $t->string('type');          // 'file'
    $t->string('slot');
    $t->json('payload');         // { media_id, title, label }
    $t->timestamps();
});
  • Use spatie/laravel-medialibrary (or plain Storage) for the file; store only the media id in payload.
  • Render through a registry so old content survives refactors:
// app/Widgets/WidgetRegistry.php
public function render(Widget $w): string {
    return view("widgets.{$w->type}", ['widget' => $w])->render();
}
  • Blade partial resources/views/widgets/file.blade.php resolves the media to a URL and emits a download link with mime/size.
  • Admin editing goes through a FormRequest + policy; validation lives there, not in the component.
  • If you're on Inertia or Livewire, keep the same payload shape and expose it via a JSON resource — the storage contract is the thing worth copying from the original.

Integration tip: the one idea worth stealing from Victoire is the stable type key plus free-form payload. It lets you add widget kinds later without migrations and keeps rendered archives readable.

Gotchas and Tips

  • Do not composer require this into a Laravel app expecting it to work. Autoload succeeds, nothing else does, and the Symfony 2.x constraints will either fail resolution outright or drag your dependency graph back a decade.
  • Last release 2016-08-22, 1 star, 0 dependents. Unmaintained, unaudited, no security response path, no tests. Treat it as read-only reference material, never as a runtime dependency.
  • Version wall. Symfony 2.7/2.8-era constraints are incompatible with Laravel 8+ (PHP 7.3+, Symfony 5/6 components). There is no supported overlap.
  • Hard coupling to Victoire's widget bundle. The entity is not usable standalone — it extends/annotates against Victoire base classes and Doctrine mappings. You can't cherry-pick it.
  • Bundle registration order matters in Symfony. If it loads before VictoireWidgetBundle/core, the widget silently never appears in the editor. No error, just absence.
  • Template overrides fail silently. Twig bundle inheritance is path-based; a typo'd override path falls back to the original markup with zero warning. Clear the cache and diff the rendered HTML when in doubt.
  • Asset/media 404s are the most common runtime bug: files live under the media bundle's web directory, so assets:install, symlinks, and chmod on the upload dir are the usual suspects.
  • Docs are effectively the Twig templates. Field names, expected nullability, and rendering semantics are only discoverable by reading edit.html.twig / show.html.twig. Don't trust class names.
  • No extension events. Extension points are exactly three: template override, form type extension, entity subclass. There's no dispatcher hook of its own.
  • Budget honestly: rebuilding this as a Blade component + medialibrary is roughly a day. Porting the bundle is a week you'll never get back, and you'll still be on dead code.
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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
cgv/localized-resource