Places
The geo field (a point), the geo_shape field (an area boundary as GeoJSON) and the address field (a country-aware postal address), with parameters, validation, stored shapes and template values.
All three are held once for every locale: where a place is does not change with the language.
geo
A point on the map: where a listing is, where a walk starts. The core event and listing types have a required, indexed location, and area an optional centre.
fields:
- name: startPoint
type: geo
required: true
index: true
bounds: { min_lat: 49.8, min_lon: -8.7, max_lat: 60.9, max_lon: 1.8 } | Parameter | Type | Default | What it does |
|---|---|---|---|
bounds | { min_lat, min_lon, max_lat, max_lon } | none | The point must fall inside this box. |
| Code | Message |
|---|---|
geo | Enter a latitude and a longitude |
lat | Latitude must be between -90 and 90 |
lon | Longitude must be between -180 and 180 |
precision | Precision must be one of rooftop, street, locality, approximate |
bounds | The point is outside the allowed area |
Stored value: { "lat": 52.0629, "lon": -1.3398, "precision": "rooftop" }. precision is optional and one of rooftop, street, locality or approximate, from a geocoder’s exact match down to a hand-placed pin. With index: true the latitude and longitude are projected, so lists can filter by a bounding box and by distance.
Template value:
| Property or method | What it is |
|---|---|
lat, lon | The coordinates. |
precision | As stored, or empty. |
derived | True on an area-style centre the engine took from the type’s boundary (below). |
distanceTo(other) | The great-circle distance in kilometres to another point (any value with lat and lon). |
staticMap(...) | A map image of the point drawn by the engine from the install’s tile provider and served from the site’s own origin, with the provider’s credit. Prints nothing when maps.tiles is not set in engine.yaml (maps); a map is a core feature, in both bundles. Options: width and height (64 to 1280; 600 and two thirds of the width by default), zoom (15), alt, name, marker (true), and any HTML attribute for the figure. |
{% for l in entry.nearbyListings %}
<p>{{ l.title }}, {{ entry.startPoint.distanceTo(l.location)|number:1 }} km away</p>
{% endfor %}
{{ entry.startPoint.staticMap(width=480, zoom=14) }} Printing the value itself shows nothing useful: read lat and lon. |distance formats metres in the viewer’s measurement system (Filters).
geo_shape
An area with an edge: a town, a national park, a council ward. The DMO bundle’s core area type has a required boundary of this type, which is what “listings in this area” containment queries test against. Use a shape, not a point with a radius, wherever “in” matters.
fields:
- name: boundary
type: geo_shape
geometries: [Polygon, MultiPolygon]
max_vertices: 10000
simplify_m: 5 | Parameter | Type | Default | What it does |
|---|---|---|---|
geometries | list of Polygon, MultiPolygon | both | The geometry types accepted. Points and lines are never accepted. |
max_vertices | whole number | 10000 | Above this, the shape is simplified on save until it fits. |
simplify_m | number | none | A Douglas-Peucker tolerance in metres applied on every save. |
The editor takes pasted GeoJSON (a geometry, a Feature or a one-feature FeatureCollection) or an uploaded GeoJSON or KML file, and draws the shape for checking. On save the shape is normalised: rings closed, duplicate consecutive vertices dropped, coordinates rounded to six decimal places, shells counter-clockwise and holes clockwise.
| Code | Message |
|---|---|
geojson | Not a usable shape: (the reason) |
geometry | Must be a Polygon or MultiPolygon |
shape | The polygon, ring and vertex that are wrong: too few vertices, coordinates off the globe, a self-intersection, a hole outside its shell |
Stored value: standard GeoJSON in WGS 84, coordinates as [lon, lat]:
{ "type": "Polygon", "coordinates": [[[-1.36, 52.05], [-1.33, 52.05], [-1.33, 52.07], [-1.36, 52.07], [-1.36, 52.05]]] } A shape is not written to the query index as such; its bounding box, centroid and area are kept for containment and distance queries.
Template value:
| Property or method | What it is |
|---|---|
type | Polygon or MultiPolygon. |
geometry | The GeoJSON, for a map script (`{{ entry.boundary.geometry |
vertices | How many vertices it has. |
areaKm2 | Its area in square kilometres, to two places. |
bbox | { minLat, minLon, maxLat, maxLon }. |
centroid | { lat, lon }. |
contains(point) | Whether a point (any value with lat and lon) is inside. |
The centre of a shape. A type with a geo_shape field and a geo field named centre gets a centre in templates even when the editor sets none: the shape’s centroid, with precision: approximate and derived: true. A centre the editor sets always wins, since the centroid of an odd shape can fall in a field.
A derived centre has lat, lon and distanceTo(), but no staticMap(): entry.centre.staticMap(...) on it prints nothing, with no error from check or render. The shape’s own centroid does have staticMap(), so draw the map from whichever exists:
{% if entry.centre and not entry.centre.derived %}{{ entry.centre.staticMap(width=480) }}{% elif entry.boundary %}{{ entry.boundary.centroid.staticMap(width=480, marker=false) }}{% endif %} address
A postal address whose parts follow the country: the components, which are required, the order of lines and the postal code pattern come from a built-in country dataset, so no country is refused and none is assumed.
fields:
- name: address
type: address
index: true
country: GB
countries: [GB, IE]
geo: true | Parameter | Type | Default | What it does |
|---|---|---|---|
country | ISO 3166 code | the site’s country | The country the editor offers first. |
countries | list of codes | every country | Restricts the countries accepted. |
geo | boolean | false | Offers a pin alongside the address. |
Components. The keys an address holds depend on the country. The common ones are line1, line2, dependent_locality, locality, administrative_area, postal_code and sorting_code; a country with no shipped data offers line1 (required), line2, locality, administrative_area and postal_code. The editor shows each country’s own labels (for the United Kingdom, “Postcode” and “Town or city”).
| Code | Message |
|---|---|
country_empty | Choose a country |
country_allowed | Must be an address in GB, IE |
required | (Label) is required, at the component |
postal_code | (Value) is not a valid (postal code label) |
script | (Code) is not a script code |
Stored value:
{
"country": "GB",
"components": { "line1": "Brewery Lane", "locality": "Hook Norton", "administrative_area": "Oxfordshire", "postal_code": "OX15 5NY" },
"formatted": ["Brewery Lane", "Hook Norton", "Oxfordshire", "OX15 5NY"],
"geo": { "lat": 51.999, "lon": -1.499 }
} formatted is computed on every save from the country’s layout; you never write it. variants may hold the same address in another script, keyed by ISO 15924 code ("Latn": { "components": { ... } }), each formatted in its own layout. With index: true the country, locality, administrative area and postal code are projected as address.country, address.locality, address.administrative_area and address.postal_code, and the pin as address.geo, so “listings in Banbury” is an indexed query.
Template value:
| Property | What it is |
|---|---|
formatted | The lines, in the country’s order, as a list. |
oneLine | The lines joined with commas. |
components | The components by key. |
country, countryName | The code and the country’s name. |
script | The script the lines are in. |
geo | The pin as a geo value, or nothing. |
A page in a locale whose script differs from the country’s, with a variant in that script, shows the variant: a Japanese address reads in Latin script on an English page when the editor gave a romanised form.
<address>{% for line in entry.address.formatted %}{{ line }}{% if not forloop.Last %}<br />{% endif %}{% endfor %}</address> Dates and times
The date field (a calendar day), the datetime field (a wall-clock time in an IANA zone with its UTC instant) and the recurrence field (an event's repeating schedule and its occurrences), with parameters, stored shapes and template values.
Phone and opening hours
The phone field (an E.164 number parsed in a region, with accepted number types) and the opening_hours field (a weekly pattern, seasons, exceptions and public holidays), with parameters, validation, stored shapes and template values.