Distance search in themes
Distance search lets visitors find listings within a distance of a city or of where they are. Site owners switch it on in Settings → General. When it is off, none of this shows and the fields below are ignored.
The form fields
Section titled “The form fields”A search form sends these, as GET fields:
| Field | Value |
|---|---|
iRadius |
5, 10, 25, 50 or 100, in the site’s unit. Other numbers snap to the nearest. |
sLat, sLng |
The visitor’s position, rounded to two decimals. |
sOrder=distance |
Nearest first. |
With iRadius and no sLat/sLng, the radius is measured from the centre of the one
city, or else the one region, in the search. The radius then replaces that city filter.
The core field
Section titled “The core field”Core adds osc_search_distance_field() to the search_form action. It prints a
<fieldset class="osc-distance" data-osc-distance> with the radius list and a
Use my location button (.osc-near-me, data-osc-near-me). Core ships no CSS for
it, so style those classes. The button needs osc-ui-common, which the field enqueues,
and it must sit inside the search <form>.
To draw it somewhere else, take it off the action and call it yourself:
osc_remove_hook('search_form', 'osc_search_distance_field');// later, in your sidebarif (osc_geo_search_enabled()) { osc_search_distance_field();}To draw your own markup, use osc_search_radius_options() for the choices,
osc_search_radius() for the current one and osc_search_near() for the point in use.
Sort and results
Section titled “Sort and results”osc_list_orders() includes Nearest first when distance search is on. A theme with
its own sort menu adds sOrder=distance&iOrderType=asc. With no distance picked,
nearest first keeps to the largest one.
On a result, osc_item_distance() is the distance in whole units of the site, or null
outside a distance search. osc_distance_label() turns a number into text such as
“25 km” or “3 miles”.
Listings from plugins
Section titled “Listings from plugins”Core sets each listing’s search point when a listing is saved through core. A plugin
that writes t_item_location itself leaves the listing out of distance search until
the weekly job sets its point.
Exact positions from an address
Section titled “Exact positions from an address”With no provider, a listing searches from its city or region centre. A geocode provider plugin finds the exact position from the listing’s street address. The owner picks it in Settings → General → Maps → Address lookup.
Core looks the address up from a job after the listing is saved, only when the listing has a
street and no position. With no provider picked, nothing is looked up; the map’s own key is
not used for it. Each answer is kept in the key-value store for as long as the provider’s cacheTtl()
allows, at most a year; an address with no match is kept for a day. A provider that
throws a RuntimeException fails the job, and the queue tries again later. A provider whose
request allowance is used up throws mindstellar\location\GeocodeLimitReached($message, $seconds)
instead: the job waits that long and tries again, with no failure counted.
ListingGeocode::queueExisting() queues the lookup of every enabled listing that has a street
and no position. One job adds them to the queue 50 at a time, and adds more only once those have run.
A provider plugin implements mindstellar\location\GeocodeProvider and registers it on
register_geocode_providers (7.0+):
osc_add_hook('register_geocode_providers', static function ($registry): void { $registry->register(new MyProvider());});geocode() returns [lat, lng] or null for no match. attribution() returns the credit
the service requires; themes echo osc_geocode_attribution() as it is, without escaping. Other code can look an
address up with osc_geocode($address, $countryCode). The geocode_address filter can rewrite
an address first, and geocode_coordinates can change or drop an answer. geocode_coordinates
runs only on a cache miss, so a cached answer skips it.
A theme that calls osc_geocode() on visitor input must cap or throttle it: each new string is a
paid call to the provider.