Using Google maps in a Wordpress plugin admin function
For a car dealer we build a couple of plugins for his new website. One plugin shows occasions where visitors can click on to get the details. With every click some information is saved in the database.
At the moment the Geo(graphical) information of the visitor is related to his IP address and not the actual location, so it is a somewhat arbitrary. Nevertheless we created a very simple map in the admin section of the plugin to show click freqencies related to towns and villages.
No additional selection for filtering is added. This article shows how easy it is to add an option to your plugin and use external API's like Google Maps
Google Maps API
In order to add a Google map to your site, you need to get a Google Maps API key for that site. This allows you to embed the maps into your web pages, and provides you with the terms and services for using the API key.
Some things you should know before you sign up for an API key:
- You must have a Google Account to get an API key. And that API key will be attached to your account.
- No limitation to the pageviews you may generate using the Maps API.
- Your service must be freely accessible to end users.
- You may not alter or obscure the logos or attribution on the map.
Additional information is available on the signup page
To use all the possibilities of Google Maps API, a good suggestion is to start here here.
Structure of the plugin
- In the plugin a menu option is added that can be clicked to show the map. This option will point to Hitlist.php.
- In the Hitlist.php the body of the HTML is defined which will be loaded when the option is clicked. Only the body is defined, for all the additional work is done by Wordpress.
- The Google API we load directly from Google.
- Map.js holds the javascript code which is executing an AJAX call to the server, processes the data and builds the map.
- This is your php script on the server that generates the JSON with the structure of the sample below. A sample script is not shown, but the JSON sample must be of help.
The file structure of the plugin
- plugins
-- CarSoftware
-- ajax
AjaxAutoLoader.php
-- html
-- hitlist
map.js
small_green_dot.png
small_red_dot.png
small_yellow_dot.png
hitlist.php
-- widgets
Carsoftware.php
JSON data structure from the server (5)
The structure of our JSON is fairly simple, for it will only contain places, their coordinates and a color that quantifies the intensity of clicks (green, yellow and red). Below is a sample of data coming from the server.
{
"data": [
[
"'s-gravendeel(4)",
"51.7812000",
"4.6176000",
null,
"red"
],
[
"'s-hertogenbosch(92)",
"51.7001990",
"5.3068000",
null,
"red"
],
...
[
"Utrecht(216)",
"52.0938000",
"5.1191000",
null,
"yellow"
],
[
"Vaassen(14)",
"52.2860980",
"5.9657000",
null,
"red"
]
]
}
- The first element is the place with the click count total for that place.
- The second element is the longitude
- The third elemenet is the latitude
- The fourth element is the z-index marker, which makes it possible to bring point forward on the map by using higher values. We don't use it in our sample.
- The fifth element is the color, which will be used to determine the color of the point on the map (red, green, yellow).
Adding menu option to the Wordpress Plugin (1)
It is assumed that is known how to write a Wordpress plugin. When this experience is available the following code should be quite clear. Our samples assumes that the plugin name is CarSoftware. Please modify this for your own purposes.
First the file CarSoftware.php file is modified to add the "hitlist" menu option to the admin functions.
function __construct() {
...
add_action('admin_menu', array($this, 'InsertAdminMenuLink'));
...
}
...
function InsertAdminMenuLink() {
add_menu_page(
__(self::PLUGIN_TITLE, self::PLUGIN_NAME), // Page Title
__(self::PLUGIN_TITLE, self::PLUGIN_NAME), // Menu Title
'manage_options', // Capability
self::PLUGIN_NAME, // Menu Slug
array($this, 'AdminPages'), // Function
plugin_dir_url(__FILE__) . '/images/car.png' // Icon
);
...
add_submenu_page(
self::PLUGIN_NAME, // parent slug
'Occasion kliks (Google Maps)', // page title
'Ocassion Kliks', // menu title
'manage_options', // capability
'CarSoftware/hitlist', // slug
array($this, 'AdminPages') // function
);
...
}
function AdminPages() {
switch ($_GET['page']):
case "CarSoftware":
$this->ConfigPageHtml();
break;
case "CarSoftware/hitlist":
$this->HitlistMap();
break;
endswitch;
}
function HitlistMap() {
$content = '';
ob_start();
require_once('html/hitlist.php');
$content = ob_get_contents();
ob_end_clean();
echo $content;
}
- The InsertAdminMenuLink is adding the menu option to the existing menu of this plugin.
- In the AdminPages function the slug is queried through a switch statement.
- The case statement is pointing to the internal function HitlistMap which is sending the hitlist.php in the folder html to the browser.
HTML/hitlist.php sending the map to the browser
The Hitlist.php is a pretty straightforwarded script that most importantly loads the Google Map API and the map.js JavaScript. Furthermore there is a placeholder for the map (#map_canvas) and some styling.
<script type="text/javascript"
src="https://maps.googleapis.com/maps/api/js?v=3&sensor=false&key=yourownverysecretgooglekey"></script>
<script type="text/javascript" src="/wp-content/plugins/GarageSoftware/html/hitlist/map.js"></script>
<style type="text/css">
body {
height: 100%;
margin: 0;
padding: 0
}
#map_canvas {
height: 100%
}
</style>
<div class="wrap occasions"> <!-- WordPress Admin pages begin with this div -->
<div id="icon-options-general" class="icon32"><br></div>
<h2>Occasion Kliks (Google Map)</h2>
<div id="map_canvas" style="width:100%; height:800px"></div>
</div>
map.js, building the Google Map (4)
In the source code below comment is added to explain every detail of the code.
jQuery(document).ready(function ($) {
// The mapOptions are used to define the general image of the
// map on the display. We also define the center of the map and the zoom
// You could make these values variable in your plugin
var mapOptions = {
zoom: 8,
maxZoom: 13,
center: new google.maps.LatLng(52.227799, 5.163574),
mapTypeId: google.maps.MapTypeId.SATELLITE
}
// The new map is bound to the DOM element map_canvas, defined
// in the Hitlist.php
var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
// trigger the loadMarkers function to bind the data to the map
loadMarkers(map);
// The AJAX call in the loadMarkers function is doing all of the work
// from here. It loads the data from the server and depending on the success
// it will show a popup on an empty map, or a lot of dots
function loadMarkers(map) {
var ajax = jQuery.ajax({
url: '/wp-content/plugins/CarSoftware/ajax/AjaxLoadHits.php',
type: 'POST',
contentType: "application/json; charset=utf-8",
dataType: "json",
async: false,
data: {
maptype: 'heatmap'
},
statusCode: {
404: function () {
alert("page not found");
}
}
});
// callback handler that will be called on success
ajax.done(function (response, textStatus, jqXHR) {
// When all is fine, the buildMarkerMap is executed
// which will bind the data to the map
var json = response;
buildMarkerMap(json.data, map);
});
// callback handler that will be called on failure
ajax.fail(function (jqXHR, textStatus, errorThrown) {
// When not fine, a simple alert is shown
// Still an empty map is shown, despite the error
alert('Oops iets ging verkeerd');
});
}
// In this function the data and the map are bound together
// The longitude and latitude are pointed on the map [1][2]
// The pointer will be a colored dot determined by the color [4]
// The title of the pointer (when hovered) is [0]
// The zIndex is added [3], but are all the same in our sample
function buildMarkerMap(data, map) {
var shape = {
coord: [1, 1, 1, 20, 18, 20, 18, 1],
type: 'poly'
};
for (var i = 0; i < data.length; i++) {
var node = data[i];
var position = new google.maps.LatLng(node[1], node[2]);
var image = new google.maps.MarkerImage('/wp-content/plugins/CarSoftware/html/hitlist/small_' + node[4] + '_dot.png', new google.maps.Size(10, 10), new google.maps.Point(0, 0), new google.maps.Point(5, 5));
var marker = new google.maps.Marker({
position: position,
map: map,
icon: image,
shape: shape,
title: node[0],
zIndex: node[3]
});
}
}
});