Why Leaflet Draw in the Admin

MapLibre GL JS does not have a built-in drawing tool. The available MapLibre drawing plugins are either unmaintained or require significant configuration. Leaflet Draw, by contrast, is mature, well-documented, and produces GeoJSON output directly — which is exactly the format needed to store polygon data in post meta and render it in MapLibre on the frontend.

The admin editor uses Leaflet only. Leaflet is not loaded on the frontend. This separation is clean: the admin concern (drawing polygons) and the frontend concern (rendering styled polygons on a custom base map) are handled by different libraries, each chosen for what it does best.

Setting Up the Admin Map Metabox

The polygon editor lives in a metabox registered on the map10_location post type. The metabox renders a div that Leaflet initializes as a map, plus a hidden input that stores the GeoJSON output. Create admin/metaboxes/location-fields.php and register the metabox:

function map10_location_metabox() {
  add_meta_box(
    'map10_location_fields',
    'Location Settings',
    'map10_location_metabox_cb',
    'map10_location',
    'normal',
    'high'
  );
}
add_action( 'add_meta_boxes', 'map10_location_metabox' );

The metabox callback outputs the map container div and the hidden input. The div needs an explicit height — Leaflet will not render in a zero-height container:

<div id="map10-admin-map" style="height:400px;width:100%;margin-bottom:12px;"></div>
<input type="hidden" name="map10_polygons" id="map10_polygons_input"
  value="<?php echo esc_attr( $polygons ); ?>">

Initializing Leaflet Draw in location-editor.js

The admin JavaScript initializes Leaflet, adds the Leaflet Draw toolbar, and loads any existing GeoJSON from the hidden input on page load. When the user finishes drawing or edits an existing polygon, the updated GeoJSON is serialized back into the hidden input so WordPress saves it on post update.

const drawnItems = new L.FeatureGroup();
map.addLayer(drawnItems);

const drawControl = new L.Control.Draw({
  edit: { featureGroup: drawnItems },
  draw: { polygon: true, polyline: false, rectangle: false, circle: false, marker: false, circlemarker: false }
});
map.addControl(drawControl);

map.on(L.Draw.Event.CREATED, function(e) {
  drawnItems.addLayer(e.layer);
  syncGeoJSON();
});
map.on(L.Draw.Event.EDITED, syncGeoJSON);
map.on(L.Draw.Event.DELETED, syncGeoJSON);

function syncGeoJSON() {
  document.getElementById('map10_polygons_input').value =
    JSON.stringify(drawnItems.toGeoJSON());
}

Auto-Calculating the Location Center from the Polygon Centroid

After a polygon is drawn, the location center coordinates (_map10_lat and _map10_lng) need to be set for marker placement. Rather than requiring the user to enter coordinates manually, auto-location-detector.js calculates the centroid of the drawn polygon and populates the lat/lng fields automatically. The centroid is calculated by averaging all polygon vertex coordinates — a simple approximation that works well for the polygon sizes used in this plugin.

This article is part of our complete guide:

How to Build an Interactive Map Plugin for WordPress from Scratch

Read the full guide →