A simple map & geolocation field, built on top of open-source services and Mapbox.
This plugin is completely free and published under the MIT license. However, if you are using it in a commercial project and want to help me keep up with maintenance, please consider making a donation of your choice.
- 1. Installation
- 2. Setup
- 3. Tile-servers
- 4. Geocoding service
- 5. Per-field options
- 6. Global options
- 7. Front-end usage
- 8. Credits
- 9. License
Kirby 3: up to 1.1.4. Kirby 4: 2.0.0+
Download and copy this repository to /site/plugins/locator
Alternatively, you can install it with composer: composer require sylvainjule/locator
Out of the box, the field is set to use open-source services both for geocoding (Nominatim) and tiles-rendering (Positron), without any API-key requirements.
Keep in mind that these services are bound by strict usage policies, always double-check if your usage is compatible. Otherwise, please set-up the field to use Mapbox, see details below.
You can also directly enter latitude / longitude coordinates and bypass the geolocation (in a format such as: 15.23456, -30.67890
).
mymap:
label: Location
type: locator
You can pick one of the 4 free tile servers included:
→ Public usage is now forbiddenwikimedia
(Terms of Use)openstreetmap
(Terms of Use)positron
(default, Terms of Use [Under Free Basemaps Terms of Service])voyager
(Terms of Use [Under Free Basemaps Terms of Service])
mymap:
type: locator
tiles: positron
You can also set this globally in your installation's main config.php
, then you won't have to configure it in every blueprint:
return array(
'sylvainjule.locator.tiles' => 'positron',
);
mapbox.outdoors→mapbox/outdoors-v11
(default mapbox theme)mapbox.streets→mapbox/streets-v11
mapbox.light→mapbox/light-v10
mapbox.dark→mapbox/dark-v10
In case your usage doesn't fall into the above policies (or if you don't want to rely on those services), you can set-up the field to use Mapbox' tiles.
You will have to set both the id
of the tiles you want to use and your mapbox public key
in your installation's main config.php
:
return array(
'sylvainjule.locator.mapbox.id' => 'mapbox/outdoors-v11',
'sylvainjule.locator.mapbox.token' => 'pk.vdf561vf8...',
);
You can now explicitely state in your blueprint that you want to use Mapbox tiles:
mymap:
type: locator
tiles: mapbox
You can also set this globally in your installation's main config.php
, then you won't have to configure it in every blueprint:
return array(
'sylvainjule.locator.tiles' => 'mapbox',
);
This is the default geocoding service. It doesn't require any additional configuration, but please double-check if your needs fit the Nominatim Usage Policy.
mymap:
type: locator
geocoding: nominatim
In case your usage doesn't fall into the above policy (or if you don't want to use Nominatim), you can set-up the field to use Mapbox API.
If you haven't already, you will have to set your mapbox public key
in your installation's main config.php
:
return array(
'sylvainjule.locator.mapbox.token' => 'pk.vdf561vf8...',
);
You can now explicitely state in your blueprint that you want to use Mapbox as a geocoding service:
mymap:
type: locator
geocoding: mapbox
You can also set this globally in your installation's main config.php
, then you won't have to configure it in every blueprint:
return array(
'sylvainjule.locator.geocoding' => 'mapbox',
);
The coordinates of the center of the map, if the field has no stored value. Default is {lat: 48.864716, lon: 2.349014}
(Paris, FR).
mymap:
type: locator
center:
lat: 48.864716
lon: 2.349014
The min
, default
and max
zoom values, where default
will be the one used on every first-load of the map. Default is: {min: 2, default: 12, max: 18}
.
mymap:
type: locator
zoom:
min: 2
default: 12
max: 18
Whether the field should store the zoom level of the map when the marker was added, and use it as default zoom value afterwards. Default is false
.
mymap:
type: locator
saveZoom: false
Whether the field should store the zoom level of the map when the user changes the zoom manually, and use it as default zoom value afterwards. Default is false
.
mymap:
type: locator
autoSaveZoom: false
The informations to be displayed in the panel. Note that it will only hide them from the panel view, they will still be stored (if available) in the .txt file. To be picked from lat
, lon
, number
, address
, postcode
, city
, region
, country
and countryCode
. Default includes them all but countryCode
.
If you are using Nominatim, the field also stores the OpenStreetMap ID under the osm
key, which you can also display by adding it to the list.
If you don't want any information to show up, set it to false
.
mymap:
type: locator
display:
- lat
- lon
- number
- address
- postcode
- city
- region
- country
- countryCode
If set to true
, the marker will be repositionable in case search result isn't precise enough. After being moved, only the new lat
and lng
will be stored. Default is true
.
If set to true
, when Mapbox is used for geocoding, you will be presented up to 5 suggestions while typing your request. Default is true
.
The style of the informations block, either columns
or table
. Default is table
.
mymap:
type: locator
liststyle: table
The color of the marker used, either dark
, light
or your own HEX value. Default is dark
.
mymap:
type: locator
marker: dark
If this option is set with an ISO 639-1 code (en, fr, de, etc.), the geocoding service will return results in the requested language if available. Default is false
.
mymap:
type: locator
language: false # or 'de' | 'fr' | 'en' | …
Whether a double click on the map should trigger a zoom (zoom
) or add a marker / move the existing marker to the coordinates of the click event (marker
). Default is zoom
.
mymap:
type: locator
dblclick: zoom # or 'marker'
The same options are available globally, which means you can set them all in your installation's config.php
file and don't worry about setting it up individually afterwards:
return array(
'sylvainjule.locator.center.lat' => 48.864716,
'sylvainjule.locator.center.lon' => 2.349014,
'sylvainjule.locator.zoom.min' => 2,
'sylvainjule.locator.zoom.default' => 12,
'sylvainjule.locator.zoom.max' => 18,
'sylvainjule.locator.saveZoom' => false,
'sylvainjule.locator.autoSaveZoom' => false,
'sylvainjule.locator.display' => array('lat','lon','number','address','postcode','city','country'),
'sylvainjule.locator.draggable' => true,
'sylvainjule.locator.autocomplete' => true,
'sylvainjule.locator.liststyle' => 'columns',
'sylvainjule.locator.marker' => 'dark',
'sylvainjule.locator.language' => false,
'sylvainjule.locator.dblclick' => 'zoom',
);
The location data is stored as YAML and therefore needs to be decoded with the yaml
method or using the toLocation
method (see below):
$location = $page->mymap()->yaml();
Potential stored keys are:
lat
(Latitude)lon
(Longitude)number
(Street number)address
(Street / road / place)city
(city / village)region
(region / state)country
(country)countryCode
(country code)osm
(OpenStreetMap ID, if using Nominatim)
It is possible that the found location doesn't have one of those keys, which will therefore not be saved. It is important to always check if the key exists, and if it's not empty. Here's one way to do it:
$location = $page->mymap()->yaml();
if(!empty($location['postcode'])) {
// there is a filled 'postcode' key
}
else {
// there is no / an empty 'postcode' key
}
Alternatively, you can use the toLocation
method to convert the value to a new collection, an use it kirby-style:
$location = $page->mymap()->toLocation();
// You now have access to
// $location->lat()
// $location->lon()
// ...
if($location->has('postcode')) {
if($location->postcode()->isNotEmpty()) {
// there is a filled 'postcode' key
}
else {
// there is an empty 'postcode' key
}
}
else {
// there is no 'postcode' key
}
Services:
- Openstreetmap, Wikimedia, Carto or Mapbox as tile servers.
- Nominatim or Mapbox Search as a geocoding API
- Leaflet as a mapping library.
K2 fields:
- Map-field by @AugustMiller
- Its open-source fork by @fendinger
MIT