Skip to content

Entries on a map ​

Show many entries on a map, each with its own popup, as one layer of markers. Write the loop yourself (e.g. {exp:channel:entries}, Low Search or Stash) and mark every entry with {maps:entry}: you keep all features of ExpressionEngine in the popup (file fields, relationships, formatting, conditionals). (from v5.0.0)

{exp:reinos_maps:map marker_cluster:enabled="yes" fit_map:markers="yes"}
    {maps:add_entries}
        {exp:channel:entries channel="stores" dynamic="no" limit="2000"}
            {maps:entry latlng="{store_location:markers_latlngs}" title="{title:attr_safe}" keys="store_{entry_id}"}
                <h3>{title}</h3>
                <img src="{store_photo}" alt="">
                <a href="{url_title_path='stores/detail'}">Details</a>
            {/maps:entry}
        {/exp:channel:entries}
    {/maps:add_entries}
{/exp:reinos_maps:map}

Maps turns the entries into one GeoJSON layer that is added with one Javascript call, so it stays fast with thousands of entries, also with marker clustering. Every entry is a normal marker: the Javascript API of the markers works with their keys (e.g. hideMarker).

​

The tag pair around the loop, inside the map tag.

url ​

Load the entries from a feed instead of the loop, after the page is loaded. Use it as a single tag:

{maps:add_entries url="{path='stores/geojson'}"}

icon:url, icon:size, icon:offset ​

The default icon of the entries: the url of the image, the size (width,height) and the point of the image on the location (x,y from the top left). An entry can have its own icon.

icon:url="/images/store.png" icon:size="32,32" icon:offset="16,32" [OPTIONAL]

The width of the popups in pixels.

popup:min_width="50" popup:max_width="300" [OPTIONAL]

​

One entry, the HTML between the tags is its popup (leave it empty for no popup).

Param
latlngThe location, 52.0907,5.1214. More locations separated by a `
addressThe address, when there is no latlng. It is geocoded once and then comes from the cache, but a latlng is faster
titleThe title of the marker (shown on hover and read by screen readers). Use {title:attr_safe}, a " in a title would end the param
keysThe keys of the marker for the Javascript API, e.g. store_{entry_id}
icon:url, icon:size, icon:offsetThe icon of this entry, see above
data:nameExtra data for your Javascript, e.g. data:category="{categories}{category_url_title} {/categories}". It is in marker.extra.name

TIP

Use :attr_safe (or single quotes around the param) for every variable in a param that can have a ".

A feed ​

For many entries or a cached map, put the loop in its own template with {exp:reinos_maps:geojson}. It outputs the entries as GeoJSON (application/geo+json), and the map loads it with {maps:add_entries url=""} after the page is loaded. Use the template caching of ExpressionEngine for the feed.

The feed template, e.g. stores/geojson:

{exp:reinos_maps:geojson}
    {exp:channel:entries channel="stores" dynamic="no" limit="5000"}
        {maps:entry latlng="{store_location:markers_latlngs}" title="{title:attr_safe}" keys="store_{entry_id}"}
            <h3>{title}</h3>
            <a href="{url_title_path='stores/detail'}">Details</a>
        {/maps:entry}
    {/exp:channel:entries}
{/exp:reinos_maps:geojson}

The map:

{exp:reinos_maps:map marker_cluster:enabled="yes" fit_map:markers="yes"}
    {maps:add_entries url="{path='stores/geojson'}"}
{/exp:reinos_maps:map}

The feed is output like a JavaScript template, whatever the type of its template: without the debug output of ExpressionEngine and the front-end editing of ExpressionEngine Pro, so it stays valid JSON when you are logged in.

The feed is a normal GeoJSON FeatureCollection, so you can use it in other apps as well. Every entry is a Point with the keys, title, popup, icon and data in its properties.

Javascript ​

The maps:entries:loaded event is fired on the document when the entries are on the map, with the mapID and the count of the markers:

js
document.addEventListener('maps:entries:loaded', function (event) {
    console.log(event.detail.count + ' stores on ' + event.detail.mapID);
});