friendsofvictoire/listing-widget
friendsofvictoire/listing-widget offers a reusable Laravel listing widget for building sortable, filterable, paginated data tables. It handles query logic, column configuration, and Blade rendering so you can add consistent list screens to admin panels and dashboards with minimal boilerplate.
Reality check before anything else: friendsofvictoire/listing-widget is not a Laravel package. It is a Symfony bundle (FriendsOfVictoire/WidgetListingBundle) that provides a "Listing" widget for Victoire DCMS, an open-source Symfony CMS. If you are on Laravel, there is no adapter, no service provider, and no Blade integration — you cannot use this package meaningfully in a Laravel app. It is only relevant if you are maintaining a legacy Symfony 2.8/3.x site built on Victoire.
Assuming you are in that situation:
Victoire\Bundle\WidgetBundle base classes.
composer require friendsofvictoire/listing-widget
app/AppKernel.php alongside the other Victoire\Widget\*Bundle entries (typically in the dev/prod bundles array, after Victoire core).php app/console cache:clear --env=dev
php app/console doctrine:schema:update --dump-sql # new widget entity => new table/columns
Entity/WidgetListing.php — the Doctrine entity holding the widget's configuration (business entity target, max results, ordering, template choice).Form/WidgetListingType.php — the editor-facing form; this tells you exactly which knobs the CMS user has.Resources/views/.../show.html.twig — the front-end render; this is where you will do 90% of your customization.Resources/config/ — service and widget registration.First use case: open a page in Victoire's front-end edit mode, drag the "Listing" widget into a slot, pick the business entity to list, set the number/order of items, save, publish. That is the package's entire scope — a configurable entity list widget inside the page builder.
Editor-driven configuration (the intended path). The widget is designed to be configured through the CMS UI, not code. Your job as a developer is usually to (a) make the business entity available/queryable, and (b) choose or override the template. Resist the urge to hardcode listing logic in PHP.
Template override — the main integration point. Override the widget's Twig template to control markup, wrapping, pagination, and item partials. In Victoire's convention this is done by placing your template at a higher-priority path (app-level Resources/ or a bundle that overrides this one) using the same relative template name, so Twig's loader resolves yours first. Keep the original as a reference and copy it before editing.
Data source pattern. The widget references a Victoire "business entity" (or a configured query) and renders a collection. Typical knobs exposed by listing-style widgets:
// illustrative shape — verify against the actual WidgetListing entity
$widget->setBusinessEntityId(...);
$widget->setMaxResults(10);
$widget->setOrderBy('createdAt');
$widget->setOrderDirection('DESC');
$widget->setTemplate('custom_list');
When you need filters the form doesn't expose, decorate the widget's rendering service or add a Twig extension rather than editing vendor code.
Programmatic creation (seeding / fixtures / imports). If you need to create listing widgets outside the UI — fixtures, content migrations, multi-site cloning — instantiate the WidgetListing entity, set its fields, persist it via Doctrine, then attach it to the page's WidgetMap/slot using Victoire's widget-map service. Always exercise this in dev first: widget maps have positional/slot semantics that are easy to corrupt, and a broken map can make the whole page fail to render.
Subclassing for reusable variants. If you repeatedly need "Listing + X", create a thin bundle whose widget entity extends WidgetListing, add the extra form fields, and register it as a distinct widget. This keeps the original untouched and gives editors a separate, clearly named widget.
Theming per site. For multi-site or multi-brand Victoire installs, map template names to per-site directories in the widget config so the same widget class renders differently per brand. This is cleaner than branching inside one template.
Testing. Cover it with a functional test that loads a published page containing the widget and asserts on rendered HTML — unit-testing the entity tells you nothing about whether the widget map, template resolution, and Doctrine query all line up.
composer.json constraints — and even then, Widget's API assumptions (Doctrine EntityManager, form types, Twig namespacing) may break.Widget entity, so it participates in Doctrine inheritance. Adding the bundle requires a doctrine:schema:update (or a hand-written migration) — forgetting this yields cryptic "table not found" errors at render time, not at boot.WidgetListing:show.html.twig-style logical names) predates modern bundle path conventions. If your override "isn't taking," confirm the exact logical name from the original config rather than guessing the file path.WidgetListing instance in the template ({{ dump(widget) }} in dev), confirm the configured entity/limit/order are actually persisted, then confirm the query returns rows. Most "broken widget" reports are empty query results, not rendering bugs.vendor/ — you will lose them on the next composer install, and there will be no upstream release to carry your fix.How can I help you explore Laravel packages today?