Map of United States with numbered clustered points
Insight

Problem Solved: How we used Drupal Content Entities to create Dynamic Maps

Female with long brown hair is standing smiling in front of a metal wall with a hand on one hip
Rosemary Reilman Technology Lead

Overview

The American Battlefield Trust came to us with the desire to display some of their video content on a map. Much of their content relates to various historical battlefields and locations around the world. So they charged us with how to display their video content on a map.

In the following example, we are using media entities with data from geolocated Youtube videos. Because Google’s Youtube Data API can return geolocation coordinates for video content, we used the YoutubeAPI Module with Drupal’s hook_ENTITY_TYPE_insert  to query for each media item’s latitude and longitude. 

After populating our video media entities with Youtube videos and their corresponding coordinates, we created a content type named “Database”. In this content type, a List field named “Database Content” exists to provide the client with a variety of entity types. The client will now be able to create pages showing different content types on their map. 

Screenshot of Drupal field settings form, highlighting the allowed values field

There are modules that allow content administrators to output maps via Views. However, we chose to do custom code for our purposes to not only allow additional editing, but also allow each map to be referenced in other fields, such as search results, etc.

Because the end result for these pages was going to be full page maps, we customized the node.html.twig template for the content type.

So our node—-database—-full.html.twig file looked something like this:

{% set database_content = node.field_database_content.0.value %}
{% set javascript_library = 'ik_maps/map-database-' ~ database_content %}
{% set map_name = node.getTitle() %}

{{ attach_library(javascript_library) }}
 
<div id="{{ 'map-' ~ database_content }}" class="{{ 'map-database-' ~ database_content ~'__map' }}" data-map-name="{{ map_name ~ ' Map' }}"></div>

For each of the Database Content field values, we created a library that is added via attach_library to the twig template. Because in our case, the different content types required different mapping functionality. 

We then created the javascript files and defined the libraries that initiated the maps and map functionality using Leaflet, Mapbox Tiles and Google Map Tiles.

Next a route was created to serve up the content data to generate all the markers on the map. There are several great options to do this—you could use Views Rest Export, create your own REST Resource or create your own custom route using a JSON Response

When everything came together it looked something like this:

Screenshot of page highlighting location-based videos on a map of the United States

Shortly after deploying this, the client wanted the ability to show videos within a designated radius of a location.

Instead of using URL parameters, we opted to create different fields to control this information, allowing Content Managers the ability to generate an aliased URL, along with a custom title and customized map settings, if desired.

Screenshot of Drupal form showing fields used to configure map content, center point and default zoom level

We used the form alter hook to conditionally show or hide the Filter options based on the value that was selected from the Database Content field. 

This allows a Content Manager the ability to change the output of the above map to show only videos within a 30 mile radius of a location, and change the default map tiles. This would result in a map that is more localized like this:

Screenshot of customized map showing a subset of location-based video content based on Drupal field settings

Drupal has always been a very powerful content management system and this is just one example of how we’ve been able to allow our clients to create custom and engaging content for their audiences.

Check out the live map