friendsofvictoire/filter-widget
A reusable PHP filter widget that adds configurable filtering controls to list and search-result views, helping users narrow data by multiple criteria through a clean, extensible API.
This is not a general-purpose filtering library. It is a widget bundle for Victoire DCMS — a Symfony 2/3-era CMS — that adds a "Filter" block you can drop onto a page so the rendered page lists a filtered set of Victoire BusinessEntity records. If you are not running Victoire, there is nothing here to use; evaluate doctrine/orm + a query builder directly instead.
Prerequisites (verify before you start):
VictoireCoreBundle and friends wired up in AppKernel).composer.json against whatever Victoire version you run.Minimal install:
composer require friendsofvictoire/filter-widget
// app/AppKernel.php
public function registerBundles()
{
$bundles = [
// ...
new Victoire\Bundle\CoreBundle\VictoireCoreBundle(),
new Victoire\Widget\FilterBundle\WidgetFilterBundle(), // confirm namespace from composer.json autoload / bundle class
];
}
Then:
app/console cache:clear
app/console doctrine:schema:update --dump-sql # inspect before --force
app/console debug:container | grep -i widget # see how the widget is registered
Where to look first, in this order:
README.md and composer.json — the required Victoire/Symfony version range is the whole story here. Confirm the bundle class namespace before writing AppKernel code.Widget/ (or Entity/) — the widget entity itself. This tells you exactly which fields hold the filter criteria and what getWidgetName() returns.Resources/views/ — the front-end Twig template you will almost certainly override.Resources/config/ — service definitions and the widget tag; this is where you see what the filter widget delegates to (Victoire's business-entity filter service).DependencyInjection/ — confirm there is no configuration you need to supply.First use case: log into the Victoire back office, edit a page, insert the Filter widget into a slot, choose the target BusinessEntity (e.g. Article, Product), add criteria, publish, and see the filtered list render on the front end.
Configure in the CMS, not in code. The intended workflow is: the editor picks the business entity and the conditions in the widget form; the widget serializes that configuration onto the widget entity; the front-end template resolves it against the query builder on render. Treat the stored widget configuration as user data, not as a config file.
Override the template — don't fork the bundle. The highest-leverage change is almost always presentation. Copy the widget's Twig template into your app's override path and edit it:
{# app/Resources/WidgetFilterBundle/views/Widget/show.html.twig #}
{# verify the exact subpath against Resources/views in the package #}
{% extends 'VictoireWidgetFilterBundle:Widget:show.html.twig' %}
{% block content %}
<ul class="results">
{% for item in filteredBusinessEntities %}
<li><a href="{{ path('victoire_core_page_show', pathVariables) }}">{{ item }}</a></li>
{% endfor %}
</ul>
{% endblock %}
Inspect the shipped template first for the real variable names exposed by the widget — do not assume filteredBusinessEntities.
Reuse the filter service outside the widget. When you need the same filtering on a custom controller or a REST endpoint, inject the Victoire filter service directly rather than going through the widget:
// services.yml
my.service:
class: AppBundle\Service\ProductLister
arguments: ['@victoire.business_entity.filter'] # confirm service id from Resources/config
// in the service
$queryBuilder = $this->filter->buildQueryBuilder($businessEntityName, $criteria);
$queryBuilder->setMaxResults(20)->addOrderBy('e.createdAt', 'DESC');
This is the intended escape hatch: the widget is a thin UI over a filter abstraction, so most real work happens in your BusinessEntity class and the filter service.
Add a new criterion type by implementing Victoire's filter interface and tagging the service. That is the cleanest extension point — you keep the widget as-is and gain a new operator/field type for editors. Copy an existing filter class from vendor/victoire/ as the template.
Sort/paginate downstream. The widget gives you a filtered result set; it does not give you a pager. Attach KnpPaginator or a Pagerfanta adapter to the query builder and render the pager in your overridden template.
Theme/translation awareness. Widget content and labels are translatable in Victoire. Keep any new strings in the widget's translation domain rather than hardcoding them in the Twig override, otherwise multilingual pages drift.
vendor replacements (repositories in composer.json) rather than hoping for upstream fixes.doctrine:schema:update --dump-sql and review before --force. Victoire widget entities commonly share inheritance strategies; a careless update can touch more tables than you expect.app/console cache:clear --env=dev plus a hard browser refresh. If the widget "disappears" from the picker, it is usually a stale cache or a missing/failed service tag — check debug:container and debug:event-dispatcher.dump() it in the template or a listener)? (4) is the Twig override actually being picked up (add a marker comment)? Each stage fails independently.How can I help you explore Laravel packages today?