Search
Try it
One field, every kind of result. Page names come from the router and need no declaration; records come from the entities carrying the attribute below. Each result carries where it goes, so the bar has nothing to decide about what a click means.
Providers
A provider is one family of findable things. Implementing the interface is the whole registration — autoconfiguration tags it, so a provider written in an application joins the search by existing. These are the ones answering here, by the name a query restricts itself to.
-
entity
Wexample\SymfonySearch\Class\Provider\EntitySearchProvider
-
route
Wexample\SymfonySearch\Class\Provider\RouteSearchProvider
class CommandSearchProvider extends AbstractSearchProvider
{
public function provide(SearchQuery $query): iterable
{
// yield $this->createResult($reference, $title)->setScore($score);
}
}
Searchable entities
The class says an entity is findable; its properties say on what, each with its kind — a title is read, an amount is a figure, an address is whole or nothing — and the kind decides both the SQL and the points. Six of the legacy's seven scoring functions were that list in disguise. The seventh reasoned, and that one names a scoring class; the entity whose answer depends on who is asking adds provider: true and gets a provider of its own.
-
contact
Wexample\SymfonyOrganization\Entity\Contact
Fields : name (text), email (email) -
demo_message
Wexample\SymfonyDesignSystemDemo\Entity\DemoMessage
Fields : body (text, 5) -
demo_room
Wexample\SymfonyDesignSystemDemo\Entity\DemoRoom
Fields : name (text) -
demo_user
Wexample\SymfonyUserDemo\Entity\DemoUser
Fields : email (email), username (text), firstName (text), lastName (text) -
organization
Wexample\SymfonyOrganization\Entity\Organization
Fields : name (text), vatNumber (text), legalIdentifier (text), email (email)
#[ORM\Entity]
#[Searchable(route: 'app_invoice_show')]
class Invoice extends AbstractEntity
{
#[SearchText]
protected string $label;
#[SearchAmount(points: 40)]
protected float $priceTotal;
}
The API
A result is an entity, so its endpoint is the collection of that entity and nothing else. The TypeScript repository generated from the same PHP class calls it without being told where it is — which is what the field above uses.
Query parameters
- search
What is being looked for. An empty query answers nothing rather than everything.
- context
Where the search is made from, which decides what it may answer. Shipped contexts : default, header, form_field
- type
Restricts the answer to one kind — an entity name, or a provider key.
- length
How many results. Absent, the bundle configuration decides.
curl "/api/search-result/list?search=dupont&context=header&length=5"
Translations
The bar reads its own labels from the four faces of the component, so a placeholder is never written in markup. Result titles, on the other hand, come from the record itself or from the route name — translating those is not wired yet, and a page currently shows its route name humanised.
# assets/components/search-bar.fr.yml
placeholder: Rechercher...
empty: Aucun résultat.
pending: Recherche en cours...