friendsofvictoire/picturecomparator-widget
A Laravel Blade widget for interactive side-by-side picture comparison. Add before/after images with a draggable slider, configurable labels, and simple view integration—useful for galleries, product updates, redesigns, and visual diffs.
This is not a standalone library — it's a Victoire CMS widget bundle. You need an existing Victoire 2 install (Symfony 3.4-era, PHP 7.x) before it does anything. Installing it into a plain Symfony app gets you an unusable bundle.
composer require friendsofvictoire/picturecomparator-widget
Register it in app/AppKernel.php (verify the exact class name by listing the bundle directory in vendor/ — Victoire bundles follow Victoire\Widget\<Name>Bundle\VictoireWidget<Name>Bundle):
new Victoire\Widget\PictureComparatorBundle\VictoireWidgetPictureComparatorBundle(),
Then rebuild:
php app/console cache:clear
php app/console assets:install --symlink web
First use case: open a page in Victoire's editor, drag the PictureComparator widget into a slot, upload your "before" and "after" images into its media fields, set any caption/orientation options, publish, and confirm the comparison slider works on the front end.
Where to look first, in this order:
Entity/WidgetPictureComparator.php — the persisted fields. This tells you exactly what the Twig template exposes (widget.pictureBefore, etc.) and is the fastest way to understand the widget.Resources/views/show.html.twig — front-end markup. You will almost certainly override this.Form/WidgetPictureComparatorType.php — what editors see and can configure.Resources/public/ — the slider CSS/JS, if it ships any.DependencyInjection/ and Resources/config/ — how it registers itself with Victoire.Template override rather than fork. The standard Symfony bundle-override path still applies:
app/Resources/VictoireWidgetPictureComparatorBundle/views/show.html.twig
Copy the vendor template there and edit. This is the normal day-to-day move: change markup, add classes, add alt text and <noscript> fallbacks, and wire in your own slider script instead of whatever ships with the bundle. Overrides are compiled, so cache:clear after every change.
Build it once as a reusable page template. Editors shouldn't hand-place a comparator on every page. Place the widget into a Victoire template (or a business-entity page template) so content editors only fill in the images. That's the pattern Victoire is designed around and it's where the bundle actually saves time.
Seed content programmatically if you have fixture/import needs. If the widget follows the standard Victoire shape, you can instantiate the widget entity, set its media relations to Victoire\Bundle\MediaBundle\Entity\Media objects, and attach it to a slot via Victoire's page/widget managers. Do this only after you've read the entity — field names and cascade settings vary between widgets, and a half-populated widget will render a broken slider rather than throwing.
Asset pipeline. If you're on Assetic, the bundle's public assets land in web/bundles/victoirewidgetpicturecomparator/. If you're on Webpack Encore (increasingly common even on old Victoire installs), don't reference that path — copy the slider JS into your own bundle and import it, so you get versioning and don't depend on assets:install having been run on deploy.
Scope your CSS. Give the override a wrapper class (e.g. .vc-picture-comparator) and namespace everything under it. Old widget CSS tends to be global and will fight your theme.
Lazy-load the images. The base template almost certainly emits plain <img> tags. Replace them in your override with loading="lazy" and srcset — a full-width before/after pair is usually the heaviest thing on the page.
"~1.0" or whatever the actual tag is), commit composer.lock, and run composer why-not friendsofvictoire/picturecomparator-widget symfony/framework-bundle 4.0 before any Symfony upgrade. Expect it to be the blocker.src/ under your own namespace and register it as a local widget bundle. That is usually less work than patching around it.cache:clear, then confirm the bundle is actually in AppKernel, then debug:container | grep -i comparator to see whether Victoire's widget compiler pass picked it up. A missing DI extension or a wrong getWidgetName() is the usual culprit.victoire_media storage path permissions and your upload config before suspecting the widget.data-initialized attribute or init once from your layout only.{{ dump(widget) }} with Twig debug enabled in the overridden template is faster than reading the entity for the tenth time. Victoire's own debug commands vary by version — don't assume they exist.vendor/ — there's no upstream to send fixes to.How can I help you explore Laravel packages today?