SlideShare a Scribd company logo
Building Responsive Maps
with WordPress
Presented by

Alicia Duffy & Ben Bond
Norfolk, VA

Saturday, November 23, 13
Alicia Duffy
Designer & Front-End Developer
@bedsheet / aliciad@petaf.org

Ben Bond
PHP Developer
@benniestacks / bennyb@petaf.org

Norfolk, VA / www.peta.org

Saturday, November 23, 13
THE CATALYST:

peta2's Vegan Campus Map
Project
Requirements:
• Each school is a
WordPress post
• School provides
their address
• Color-coded map
by ranking
• Must be responsive
and mobile-friendly

Saturday, November 23, 13
Screenshot of custom post type + meta + taxonomy

Saturday, November 23, 13
Zip Code -> Coordinates
PHP
add_action('load-post.php', 'generic_map_admin_init');
add_action('load-post-new.php', 'generic_map_admin_init');!
function generic_map_admin_init() {
$screen = get_current_screen();
wp_register_script( 'googlemaps', 'http://
maps.googleapis.com/maps/api/js?
v=3&key=API_KEY&sensor=false' );
wp_register_script( 'field-geocode', 'field-geocode.js',
array( 'jquery', 'googlemaps' ), '', true );
! ! ! ! ! ! !
! ! !
if ( $screen->id == 'location' ) { ! !
!
! wp_enqueue_script( 'googlemaps' ); ! !
! wp_enqueue_script( 'field-geocode' );
}
} !

Saturday, November 23, 13
Find zip code meta, get coordinates
Javascript / field-geocode.js
jQuery.fn.codeAddress = function () {
! var geocoder = new google.maps.Geocoder();
! var zip = $'input[name="zip_code"]').attr('value');
! if(zip != '') {
! ! geocoder.geocode( { 'address': zip},
function(results, status) {
!
if (status == google.maps.GeocoderStatus.OK) {
var coordinates =
results[0].geometry.location.lng() + ", " +
results[0].geometry.location.lat();
$'input[name="coordinates"]').attr('value',
coordinates);
!
} else {
!
! alert("Geocode failed: " + status);
!
}
});
! }
}$(document).codeAddress();

Saturday, November 23, 13
After ZIP is entered, get coordinates
Javascript / field-geocode.js (..continued)
var typingTimer;
Text
var doneTypingInterval = 1000; // 1 second
!
$("input#zip_code").keyup(function(){
typingTimer = setTimeout(function() {
$(document).codeAddress();
}, doneTypingInterval);
});
$("input#zip_code").keydown(function(){
clearTimeout(typingTimer);
});!

Saturday, November 23, 13
LeafletJS

https://github.com/Leaflet/Leaflet

Open Source + HTML5 + Supports IE7+
Very Customizable

Saturday, November 23, 13
Add Leaflet to WordPress
wp_register_style( 'leaflet_style', 'leaflet-0.6.3.css',
'', '0.6.3' );
wp_register_script( 'leaflet-js', 'leaflet-0.6.3.js',
'', '0.6.3', true );
wp_register_script( 'leaflet-config', 'leafletconfig.js', '', '', true );
wp_enqueue_style( 'leaflet_style' );
// Register shortcode
add_shortcode('leaflet-map', 'generic_map_shortcode');
function generic_map_shortcode($atts) {
! wp_enqueue_script( 'leaflet-js' );
! wp_enqueue_script( 'leaflet-config' );
! echo '<div class="map-inner" style="width: 100%;
height: 500px;"><div id="map" style="width: 100%;
height: 100%;"></div></div>';
}
Saturday, November 23, 13
Basic Leaflet Map
Javascript / leaflet-config.js
var map = L.map('map').setView([51.505, -0.09], 13);
L.tileLayer('http://{s}.tile.cloudmade.com/API-KEY/1/256/
{z}/{x}/{y}.png', {
! attribution: 'Map data &copy; 2013 OpenStreetMap
contributors, Imagery &copy; 2013 CloudMade',
! key: 'API-KEY'
}).addTo(map);
! !
L.marker([51.5, -0.09]).addTo(map)
.bindPopup('A pretty CSS3 popup. <br> Easily
customizable.')
.openPopup();!

*See https://github.com/leaflet-extras/leaflet-providers
for more map choices.

Saturday, November 23, 13
Screenshot of custom post type + meta + taxonomy

Saturday, November 23, 13
How to map 1000+ posts?
Output all the posts as a geoJSON object
var locationMap = {
! "type": "FeatureCollection",
! "features": [{
"geometry": {
"type": "Point",
"coordinates": [-78.72000000000003, 35.81]
},
"type": "Feature",
"properties": {
"name": "WordCamp Raleigh",
"link": "http://localhost:8888/location/17/",
"symbol": "star"
},
"id": 1
}]
};

Saturday, November 23, 13
Generate the GeoJSON file
query_posts($query_string.'&order=DEC&posts_per_page=2000');
if( isset($_REQUEST['geo']) ) {
if( have_posts() ) {
while( have_posts() ) {
! ! the_post();
! ! $output[]=array(
! ! ! 'title' => get_the_title(),
! ! ! 'meta' => get_post_custom(),
! ! ! 'id'
=> get_the_id()
! ! );
}
}
}
$upload_dir = wp_upload_dir();
$theFile = $upload_dir['basedir'].'/geojson.php';
$expiration_date = strtotime("+1 day");
$now = strtotime("now");
Saturday, November 23, 13
Check File Expiration
$expiration_date = '.$expiration_date.';
$now = strtotime("now");
! !
if ( $expiration_date < $now ) {
! $refresh_file = file_get_contents("'.$callFile.'");
! if ( $refresh_file ) {
! ! echo file_get_contents("'.$cacheFile.'");
! }
} else {
//Display new cache file

Saturday, November 23, 13
foreach ($output as $key => $value) {
! $terms = get_the_terms($value['id'], 'location_symbol');
! $term = array_pop($terms);
! $fileContents .='
! ! {
! ! ! "geometry": {
! ! ! ! "type": "Point",
! ! ! ! "coordinates": [' . $value['meta']
['coordinates'][0] . ']
! ! ! },
! ! ! "type": "Feature",
! ! ! "properties": {
! ! ! ! "name": "' . $value['title'] . '",
! ! ! ! "link": "' . get_permalink($value['id']) . '",
! ! ! ! "symbol": "' . $term‐>name . '"
! ! ! },
! ! "id": ' . $count . '
! ! },
! ';
! ! $count++;
! }

Saturday, November 23, 13
Map each location
PHP
wp_register_script( 'geojson', get_site_url() . '/wpcontent/uploads/geojson.php', array( 'jquery' ), '', true );
Javascript / leaflet-config.js
L.geoJson(locationMap, {
! pointToLayer: function(feature, coordinates) {
! ! return L.marker(coordinates);
! },
! onEachFeature: onEachFeature
}).addTo(map);
function onEachFeature(feature, layer) {
! var popupContent = "<h4><a href='" +
feature.properties.link + "'>" + feature.properties.name +
"</a></h4>";
! layer.bindPopup(popupContent, {maxWidth:200});!
}

Saturday, November 23, 13
Screenshot of custom post type + meta + taxonomy

Saturday, November 23, 13
Customize Map Markers

• Awesome Leaflet Markers

https://github.com/lvoogdt/
Leaflet.awesome-markers

• Colorful & retina-proof markers for Leaflet
• Can use a taxonomy or meta field to
differentiate markers

• Uses web fonts for the icons

Saturday, November 23, 13
Icon-ize our Markers
PHP
wp_register_style( 'font_awesome', 'font-awesome.min.css');
wp_register_style( 'leaflet_markers', 'leaflet.awesome-markers.css');
wp_register_script( 'leaflet-awesome-markers', 'leaflet.awesome-markers.js', '',
'', true );

Javascript
L.geoJson(locationMap, {
!
pointToLayer: function(feature, coordinates) {
!
!
return L.marker(coordinates, {icon: L.AwesomeMarkers.icon({icon:
feature.properties.symbol, prefix: 'fa', markerColor:
randomColor(feature.properties.symbol)}) });
!
},
!
onEachFeature: onEachFeature
}).addTo(map);
function randomColor() {
!
var colors = Array('red', 'darkred', 'orange', 'green', 'darkgreen', 'blue',
'purple', 'darkpuple', 'cadetblue');
!
var color = colors[Math.floor(Math.random()*colors.length)];
!
return color;
}

Saturday, November 23, 13
Screenshot of custom post type + meta + taxonomy

Saturday, November 23, 13
Generic Map Plugin
A starting off point for making maps in WordPress
https://github.com/aliciaduffy/generic-map

•
•

Creates location post type and custom taxonomy

•

Generates an updated geoJSON object daily, w/
option to manually refresh

•

Adds a [leaflet-map] shortcode to easily drop the
map onto any page

Adds ZIP code and latitude/longitude custom meta
fields

Saturday, November 23, 13

More Related Content

PDF
Building Maps with Leaflet
PDF
Application devevelopment with open source libraries
PPTX
Building books from static sites: Digital (and print) publishing with the JAM...
PDF
CPOSC Talk - The Gatsby, Contentful, Netlify Stack
PDF
Google Maps API 101
KEY
GeoTechTalk InkSatogaeri Project
PDF
Webgl para JavaScripters
PPT
Google Maps API
Building Maps with Leaflet
Application devevelopment with open source libraries
Building books from static sites: Digital (and print) publishing with the JAM...
CPOSC Talk - The Gatsby, Contentful, Netlify Stack
Google Maps API 101
GeoTechTalk InkSatogaeri Project
Webgl para JavaScripters
Google Maps API

Viewers also liked (20)

PPS
M E N U C U A R E S M A L
DOC
Curriculum specification F5
PDF
Tutorial 1.4 - Explore results in a heatmap
DOCX
La graviola
ODP
Apache sirona
PPS
¡ALIMENTOS Y MALESTARES!
PPTX
Test King Virtual Test--Network+
PPS
Recomenzar
KEY
The Evolution of Live Preview Environment Design
PDF
UX Munich2015
PDF
Virtual Event Planning
PDF
Design &amp; Evaluation Edu-Game
PPS
¡LA BELLEZA DE LOS ARBOLES!
ODP
Juc paris olivier lamy talk
PPTX
Good library use
PPS
¡NÓ! LECHE DE VACA
PDF
Tutorial 1.2 - Import modules from Biomart
PDF
Tutorial 1.1 - Import Intogen tumor types
PPS
82378 andrea bocelli-y_celline_dion-1
PPTX
1ra clase cómo optimizar la busqueda en google
M E N U C U A R E S M A L
Curriculum specification F5
Tutorial 1.4 - Explore results in a heatmap
La graviola
Apache sirona
¡ALIMENTOS Y MALESTARES!
Test King Virtual Test--Network+
Recomenzar
The Evolution of Live Preview Environment Design
UX Munich2015
Virtual Event Planning
Design &amp; Evaluation Edu-Game
¡LA BELLEZA DE LOS ARBOLES!
Juc paris olivier lamy talk
Good library use
¡NÓ! LECHE DE VACA
Tutorial 1.2 - Import modules from Biomart
Tutorial 1.1 - Import Intogen tumor types
82378 andrea bocelli-y_celline_dion-1
1ra clase cómo optimizar la busqueda en google
Ad

Similar to Responsive Maps in WordPress (20)

ZIP
Web+GISという視点から見たGISの方向性
PDF
Cheap frontend tricks
PDF
ESRI Dev Meetup: Building Distributed JavaScript Map Widgets
PDF
Das Web Wird Mobil - Geolocation und Location Based Services
PDF
An Introduction to Jquery
PDF
Mobile Application Development for the Web Developer
PPT
JQuery Flot
KEY
Barcamp GoogleMaps - praktické ukázky kódu
PDF
Writing Maintainable JavaScript
PDF
PDF
Using jQuery to Extend CSS
PDF
AngularJS: The Bridge Between Today and Tomorrow's Web (Todd Motto)
KEY
Alpha Streaming Realtime
KEY
Evrone.ru / BEM for RoR
KEY
Ioannis Doxaras on GIS and Gmaps at 1st GTUG meetup Greece
PDF
Building Evented Single Page Applications
PDF
Building evented single page applications
TXT
Photostream
TXT
Photostream
PDF
OL4JSF - Latinoware 2010
Web+GISという視点から見たGISの方向性
Cheap frontend tricks
ESRI Dev Meetup: Building Distributed JavaScript Map Widgets
Das Web Wird Mobil - Geolocation und Location Based Services
An Introduction to Jquery
Mobile Application Development for the Web Developer
JQuery Flot
Barcamp GoogleMaps - praktické ukázky kódu
Writing Maintainable JavaScript
Using jQuery to Extend CSS
AngularJS: The Bridge Between Today and Tomorrow's Web (Todd Motto)
Alpha Streaming Realtime
Evrone.ru / BEM for RoR
Ioannis Doxaras on GIS and Gmaps at 1st GTUG meetup Greece
Building Evented Single Page Applications
Building evented single page applications
Photostream
Photostream
OL4JSF - Latinoware 2010
Ad

Recently uploaded (20)

PPTX
EDP Competencies-types, process, explanation
PPTX
2. Competency Based Interviewing - September'16.pptx
PDF
Interior Structure and Construction A1 NGYANQI
PPTX
22CDH01-V3-UNIT-I INTRODUCITON TO EXTENDED REALITY
PDF
Test slideshare presentation for blog post
PDF
Chalkpiece Annual Report from 2019 To 2025
PPT
pump pump is a mechanism that is used to transfer a liquid from one place to ...
PDF
Architecture Design Portfolio- VICTOR OKUTU
PPTX
timber basics in structure mechanics (dos)
PDF
SOUND-NOTE-ARCHITECT-MOHIUDDIN AKHAND SMUCT
PPTX
VERNACULAR_DESIGN_PPT FINAL WITH PROPOSED PLAN.pptx
PDF
2025CategoryRanking of technology university
PDF
2025_AIFG_Akane_Kikuchi_Empathy_Design.PDF
PPTX
Evolution_of_Computing_Presentation (1).pptx
PDF
Strengthening Tamil Identity A. Swami Durai’s Legacy
PPTX
22CDH01-V3-UNIT III-UX-UI for Immersive Design
PDF
Skskkxiixijsjsnwkwkaksixindndndjdjdjsjjssk
PDF
Introduction-to-World-Schools-format-guide.pdf
PPTX
CLASSIFICATION OF YARN- process, explanation
PDF
Urban Design Final Project-Context
EDP Competencies-types, process, explanation
2. Competency Based Interviewing - September'16.pptx
Interior Structure and Construction A1 NGYANQI
22CDH01-V3-UNIT-I INTRODUCITON TO EXTENDED REALITY
Test slideshare presentation for blog post
Chalkpiece Annual Report from 2019 To 2025
pump pump is a mechanism that is used to transfer a liquid from one place to ...
Architecture Design Portfolio- VICTOR OKUTU
timber basics in structure mechanics (dos)
SOUND-NOTE-ARCHITECT-MOHIUDDIN AKHAND SMUCT
VERNACULAR_DESIGN_PPT FINAL WITH PROPOSED PLAN.pptx
2025CategoryRanking of technology university
2025_AIFG_Akane_Kikuchi_Empathy_Design.PDF
Evolution_of_Computing_Presentation (1).pptx
Strengthening Tamil Identity A. Swami Durai’s Legacy
22CDH01-V3-UNIT III-UX-UI for Immersive Design
Skskkxiixijsjsnwkwkaksixindndndjdjdjsjjssk
Introduction-to-World-Schools-format-guide.pdf
CLASSIFICATION OF YARN- process, explanation
Urban Design Final Project-Context

Responsive Maps in WordPress

  • 1. Building Responsive Maps with WordPress Presented by Alicia Duffy & Ben Bond Norfolk, VA Saturday, November 23, 13
  • 2. Alicia Duffy Designer & Front-End Developer @bedsheet / aliciad@petaf.org Ben Bond PHP Developer @benniestacks / bennyb@petaf.org Norfolk, VA / www.peta.org Saturday, November 23, 13
  • 3. THE CATALYST: peta2's Vegan Campus Map Project Requirements: • Each school is a WordPress post • School provides their address • Color-coded map by ranking • Must be responsive and mobile-friendly Saturday, November 23, 13
  • 4. Screenshot of custom post type + meta + taxonomy Saturday, November 23, 13
  • 5. Zip Code -> Coordinates PHP add_action('load-post.php', 'generic_map_admin_init'); add_action('load-post-new.php', 'generic_map_admin_init');! function generic_map_admin_init() { $screen = get_current_screen(); wp_register_script( 'googlemaps', 'http:// maps.googleapis.com/maps/api/js? v=3&key=API_KEY&sensor=false' ); wp_register_script( 'field-geocode', 'field-geocode.js', array( 'jquery', 'googlemaps' ), '', true ); ! ! ! ! ! ! ! ! ! ! if ( $screen->id == 'location' ) { ! ! ! ! wp_enqueue_script( 'googlemaps' ); ! ! ! wp_enqueue_script( 'field-geocode' ); } } ! Saturday, November 23, 13
  • 6. Find zip code meta, get coordinates Javascript / field-geocode.js jQuery.fn.codeAddress = function () { ! var geocoder = new google.maps.Geocoder(); ! var zip = $'input[name="zip_code"]').attr('value'); ! if(zip != '') { ! ! geocoder.geocode( { 'address': zip}, function(results, status) { ! if (status == google.maps.GeocoderStatus.OK) { var coordinates = results[0].geometry.location.lng() + ", " + results[0].geometry.location.lat(); $'input[name="coordinates"]').attr('value', coordinates); ! } else { ! ! alert("Geocode failed: " + status); ! } }); ! } }$(document).codeAddress(); Saturday, November 23, 13
  • 7. After ZIP is entered, get coordinates Javascript / field-geocode.js (..continued) var typingTimer; Text var doneTypingInterval = 1000; // 1 second ! $("input#zip_code").keyup(function(){ typingTimer = setTimeout(function() { $(document).codeAddress(); }, doneTypingInterval); }); $("input#zip_code").keydown(function(){ clearTimeout(typingTimer); });! Saturday, November 23, 13
  • 8. LeafletJS https://github.com/Leaflet/Leaflet Open Source + HTML5 + Supports IE7+ Very Customizable Saturday, November 23, 13
  • 9. Add Leaflet to WordPress wp_register_style( 'leaflet_style', 'leaflet-0.6.3.css', '', '0.6.3' ); wp_register_script( 'leaflet-js', 'leaflet-0.6.3.js', '', '0.6.3', true ); wp_register_script( 'leaflet-config', 'leafletconfig.js', '', '', true ); wp_enqueue_style( 'leaflet_style' ); // Register shortcode add_shortcode('leaflet-map', 'generic_map_shortcode'); function generic_map_shortcode($atts) { ! wp_enqueue_script( 'leaflet-js' ); ! wp_enqueue_script( 'leaflet-config' ); ! echo '<div class="map-inner" style="width: 100%; height: 500px;"><div id="map" style="width: 100%; height: 100%;"></div></div>'; } Saturday, November 23, 13
  • 10. Basic Leaflet Map Javascript / leaflet-config.js var map = L.map('map').setView([51.505, -0.09], 13); L.tileLayer('http://{s}.tile.cloudmade.com/API-KEY/1/256/ {z}/{x}/{y}.png', { ! attribution: 'Map data &copy; 2013 OpenStreetMap contributors, Imagery &copy; 2013 CloudMade', ! key: 'API-KEY' }).addTo(map); ! ! L.marker([51.5, -0.09]).addTo(map) .bindPopup('A pretty CSS3 popup. <br> Easily customizable.') .openPopup();! *See https://github.com/leaflet-extras/leaflet-providers for more map choices. Saturday, November 23, 13
  • 11. Screenshot of custom post type + meta + taxonomy Saturday, November 23, 13
  • 12. How to map 1000+ posts? Output all the posts as a geoJSON object var locationMap = { ! "type": "FeatureCollection", ! "features": [{ "geometry": { "type": "Point", "coordinates": [-78.72000000000003, 35.81] }, "type": "Feature", "properties": { "name": "WordCamp Raleigh", "link": "http://localhost:8888/location/17/", "symbol": "star" }, "id": 1 }] }; Saturday, November 23, 13
  • 13. Generate the GeoJSON file query_posts($query_string.'&order=DEC&posts_per_page=2000'); if( isset($_REQUEST['geo']) ) { if( have_posts() ) { while( have_posts() ) { ! ! the_post(); ! ! $output[]=array( ! ! ! 'title' => get_the_title(), ! ! ! 'meta' => get_post_custom(), ! ! ! 'id' => get_the_id() ! ! ); } } } $upload_dir = wp_upload_dir(); $theFile = $upload_dir['basedir'].'/geojson.php'; $expiration_date = strtotime("+1 day"); $now = strtotime("now"); Saturday, November 23, 13
  • 14. Check File Expiration $expiration_date = '.$expiration_date.'; $now = strtotime("now"); ! ! if ( $expiration_date < $now ) { ! $refresh_file = file_get_contents("'.$callFile.'"); ! if ( $refresh_file ) { ! ! echo file_get_contents("'.$cacheFile.'"); ! } } else { //Display new cache file Saturday, November 23, 13
  • 15. foreach ($output as $key => $value) { ! $terms = get_the_terms($value['id'], 'location_symbol'); ! $term = array_pop($terms); ! $fileContents .=' ! ! { ! ! ! "geometry": { ! ! ! ! "type": "Point", ! ! ! ! "coordinates": [' . $value['meta'] ['coordinates'][0] . '] ! ! ! }, ! ! ! "type": "Feature", ! ! ! "properties": { ! ! ! ! "name": "' . $value['title'] . '", ! ! ! ! "link": "' . get_permalink($value['id']) . '", ! ! ! ! "symbol": "' . $term‐>name . '" ! ! ! }, ! ! "id": ' . $count . ' ! ! }, ! '; ! ! $count++; ! } Saturday, November 23, 13
  • 16. Map each location PHP wp_register_script( 'geojson', get_site_url() . '/wpcontent/uploads/geojson.php', array( 'jquery' ), '', true ); Javascript / leaflet-config.js L.geoJson(locationMap, { ! pointToLayer: function(feature, coordinates) { ! ! return L.marker(coordinates); ! }, ! onEachFeature: onEachFeature }).addTo(map); function onEachFeature(feature, layer) { ! var popupContent = "<h4><a href='" + feature.properties.link + "'>" + feature.properties.name + "</a></h4>"; ! layer.bindPopup(popupContent, {maxWidth:200});! } Saturday, November 23, 13
  • 17. Screenshot of custom post type + meta + taxonomy Saturday, November 23, 13
  • 18. Customize Map Markers • Awesome Leaflet Markers https://github.com/lvoogdt/ Leaflet.awesome-markers • Colorful & retina-proof markers for Leaflet • Can use a taxonomy or meta field to differentiate markers • Uses web fonts for the icons Saturday, November 23, 13
  • 19. Icon-ize our Markers PHP wp_register_style( 'font_awesome', 'font-awesome.min.css'); wp_register_style( 'leaflet_markers', 'leaflet.awesome-markers.css'); wp_register_script( 'leaflet-awesome-markers', 'leaflet.awesome-markers.js', '', '', true ); Javascript L.geoJson(locationMap, { ! pointToLayer: function(feature, coordinates) { ! ! return L.marker(coordinates, {icon: L.AwesomeMarkers.icon({icon: feature.properties.symbol, prefix: 'fa', markerColor: randomColor(feature.properties.symbol)}) }); ! }, ! onEachFeature: onEachFeature }).addTo(map); function randomColor() { ! var colors = Array('red', 'darkred', 'orange', 'green', 'darkgreen', 'blue', 'purple', 'darkpuple', 'cadetblue'); ! var color = colors[Math.floor(Math.random()*colors.length)]; ! return color; } Saturday, November 23, 13
  • 20. Screenshot of custom post type + meta + taxonomy Saturday, November 23, 13
  • 21. Generic Map Plugin A starting off point for making maps in WordPress https://github.com/aliciaduffy/generic-map • • Creates location post type and custom taxonomy • Generates an updated geoJSON object daily, w/ option to manually refresh • Adds a [leaflet-map] shortcode to easily drop the map onto any page Adds ZIP code and latitude/longitude custom meta fields Saturday, November 23, 13