Widgets

Every widget is a thin wrapper over the methods on search. They exist so a listing can be built in five lines, not so anyone is obliged to use them.

WidgetNotes
searchBox({ placeholder, label })A GET form. Carries the active refinements as hidden fields, so typing does not silently clear them.
refinementList(facet, { limit, label })Values past limit go inside a <details>, which opens without JavaScript.
hierarchicalMenu(facet, { maxDepth, label })Children shown under an open branch.
rangeInput(facet, { step, label })Two number inputs, posting the form-only parameter names.
currentRefinements({ clearAll, clearLabel })Removable chips, including a geo “Within 8 km” chip.
sortBy(names, { label })A select plus a submit button the runtime hides.
stats({ timing, emptyLabel })“Showing 25–48 of 137”.
pagination({ window, previousLabel, nextLabel })Numbered links with previous and next.

Geo facets have no widget, deliberately: they need a point from the visitor, and only your page knows how to collect one. Build the control yourself and link to search.geoUrl().

Replacing the markup

Put a template of the same name under _caffeine/ in your own templates directory and Caffeine renders yours instead:

templates/_caffeine/refinement-list.twig
templates/_caffeine/pagination.twig

Each receives search, options, and its own variables — facet, tree, range, sortings, pages.

Two rules keep the runtime working:

  • Facet controls must be real <a href>s carrying the URL the state would produce. That is what makes the page work without JavaScript, and the runtime intercepts links rather than inventing behaviour — a <button> does nothing.
  • Keep data-caffeine-facet and data-caffeine-value on facet links if you want the client transport to patch counts in place.

For entirely different markup, ignore the widgets and read the state directly. They are thin wrappers over search.facet() and search.toggleUrl(), and nothing depends on you using them.

Crawling

Facet links carry rel="nofollow". A faceted listing generates a combinatorial explosion of URLs, and inviting a crawler into all of them is how a site ends up with 40,000 near-duplicate pages. Pair that with a canonical link at search.canonicalUrl.