The Challenge: One Backend, Multiple Map Deployments
What the Client Needed from a Data Perspective
When a client asks for a map that can be managed from one place and embedded across multiple websites, the first instinct is to think about the frontend. But the decision that has the most long-term impact is not how the map looks — it is how the data is stored.
Why Structure Matters Before You Write a Single Line of Code
Location data in a WordPress map system is more complex than it appears. Each location has coordinates, but it also has a description, a URL, an image, a category, a parent map reference, and potentially polygon geometry. Store all of this in a single serialized meta field and you make querying painful. The right structure is deliberate, not accidental.
Custom Post Type vs Custom Database Table
When CPT Is the Right Choice
Custom Post Types are the right choice when your data benefits from WordPress’s built-in editorial workflow, when you want locations to be manageable through the standard WordPress admin interface, and when the data volume is manageable. CPTs give you title, content, revision history, and the full meta API for free.
When a Custom Table Makes More Sense
Custom database tables become worth the added complexity when you are dealing with very high data volumes — tens of thousands of locations or more — or when you need to perform complex spatial queries that the meta table cannot support efficiently.
What We Chose and Why
For the university project, we used two Custom Post Types: one for maps and one for locations. This gave the client a clean admin interface, full revision history, and the ability to manage locations without any custom UI. The data volume was well within CPT performance limits.
Designing the Meta Field Structure
Essential Fields: lat, lng, Description, URL, Image
Each location post stores its data across several meta fields. Separating these into individual meta fields — rather than a single serialized array — makes each value independently queryable and updateable.
update_post_meta( $post_id, '_map_lat', sanitize_text_field( $_POST['map_lat'] ) );
update_post_meta( $post_id, '_map_lng', sanitize_text_field( $_POST['map_lng'] ) );
update_post_meta( $post_id, '_map_desc', sanitize_textarea_field( $_POST['map_desc'] ) );
update_post_meta( $post_id, '_map_url', esc_url_raw( $_POST['map_url'] ) );
update_post_meta( $post_id, '_map_image', esc_url_raw( $_POST['map_image'] ) );Linking Locations to a Parent Map
The relationship between a location and its parent map is stored as a meta field on the location. When the frontend requests all locations for a given map, it queries for location posts where this meta field matches the map ID.
Assigning Locations to Categories
Categories are handled via a custom taxonomy registered against the location post type. This allows locations to be filtered by category in the admin list view and makes category-based queries straightforward.
Querying Location Data Efficiently
Using get_posts with meta_key and meta_value
For a map with a moderate number of locations, get_posts with a meta query is sufficient. Keep the data preparation on the PHP side as lean as possible — only fetch the meta fields you actually need for the frontend.
Avoiding Performance Issues with Large Datasets
If the number of locations grows beyond a few hundred, consider adding a transient cache around the location query. The map data does not change on every page load — caching it for a few minutes eliminates repeated database queries without introducing significant data staleness.
Common Pitfalls in Location Data Architecture
Not Planning for Multiple Maps from the Start
The most expensive mistake in map plugin development is building for a single map and then retrofitting multi-map support. Always build with the assumption that there will be more than one map — even if the client says there will only be one.
Storing Coordinates as Strings Instead of Floats
WordPress meta values are stored as strings in the database. Always cast coordinates explicitly to float before passing them to JavaScript: (float) get_post_meta( $id, '_map_lat', true ). Passing coordinate strings to Leaflet will cause silent failures in some browsers.
Summary and What Comes Next
A well-designed data architecture is what separates a map plugin that scales from one that breaks under pressure. Use Custom Post Types for locations, store meta fields individually, link locations to maps via a meta reference, and cast coordinate values explicitly to float before use.
With the data structure in place, the next step is adding polygon support. The next article covers GeoJSON, Leaflet Draw, and how to save polygon geometry as WordPress post meta.
This article is part of our complete guide:
How to Build an Interactive Map in WordPress: A Complete Guide for Developers
Read the full guide →