responsive maps in wordpress
DESCRIPTION
This is a presentation given at WordCamp Raleigh 2013 on creating maps in WordPress with LeafletJS. Sample code here - https://github.com/aliciaduffy/generic-mapTRANSCRIPT
Building Responsive Maps with WordPress
Presented by
Alicia Duffy & Ben Bond
Norfolk, VA
Saturday, November 23, 13
Alicia DuffyDesigner & Front-End Developer
@bedsheet / [email protected]
Ben BondPHP Developer
@benniestacks / [email protected]
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
Javascript / field-geocode.jsjQuery.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();
Find zip code meta, get coordinates
Saturday, November 23, 13
TextJavascript / field-geocode.js (..continued)var typingTimer;var doneTypingInterval = 1000; // 1 second!$("input#zip_code").keyup(function(){typingTimer = setTimeout(function() {$(document).codeAddress();
}, doneTypingInterval);});
$("input#zip_code").keydown(function(){clearTimeout(typingTimer);
});!
After ZIP is entered, get coordinates
Saturday, November 23, 13
LeafletJS https://github.com/Leaflet/Leaflet
Open Source + HTML5 + Supports IE7+
Very Customizable
Saturday, November 23, 13
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', 'leaflet-config.js', '', '', true );
wp_enqueue_style( 'leaflet_style' );
// Register shortcodeadd_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>';}
Add Leaflet to WordPress
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 © 2013 OpenStreetMap contributors, Imagery © 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
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");
Generate the GeoJSON file
Saturday, November 23, 13
$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
Check File Expiration
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
PHPwp_register_script( 'geojson', get_site_url() . '/wp-content/uploads/geojson.php', array( 'jquery' ), '', true );
Javascript / leaflet-config.jsL.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});!}
Map each location
Saturday, November 23, 13
Screenshot of custom post type + meta + taxonomy
Saturday, November 23, 13
Customize Map Markers
• Awesome Leaflet Markershttps://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
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;}
Icon-ize our Markers
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
• Adds ZIP code and latitude/longitude custom meta fields
• Generates an updated geoJSON object daily, w/ option to manually refresh
• Adds a [leaflet-map] shortcode to easily drop the map onto any page
Saturday, November 23, 13