Update (Oct. 31, 2016): Google Maps now requires that you have an API Key in order to add maps via ACF. The tutorial reflects this new requirement.
One of my go-to plugins is Advanced Custom Fields. It is versatile, and makes adding custom fields to posts, pages, custom post types, and even user profiles a breeze. Unfortunately, their documentation is sometimes not very beginner friendly (I’ve written about this in the past), so today I’ll try to help out those trying to use the Google Map custom field.
Unlike some of their other custom fields, which allow you to simply use <?php the_field('field_name'); ?>
to output the content of the field for that particular post or page, this particular field, requires quite a bit of extra code. It’s all listed in their code example; I will simply explain step by step where to put in that code.
Step 0
Before you can use Google Maps you need to get a Google Map API Key. You can use the Standard API (it allows 25,000 map views per day), or if you have a lot of traffic, you’ll need to set up the Premium Plan.
Step 1
Paste this code into your stylesheet (style.css), wherever you think is appropriate:
.acf-map {
width: 100%;
height: 400px;
border: #ccc solid 1px;
margin: 20px 0;
}
Step 2
Create a new file, and copy-paste the following code in it:
(function($) {
/*
* render_map
*
* This function will render a Google Map onto the selected jQuery element
*
* @type function
* @date 8/11/2013
* @since 4.3.0
*
* @param $el (jQuery element)
* @return n/a
*/
function render_map( $el ) {
// var
var $markers = $el.find('.marker');
// vars
var args = {
zoom : 16,
center : new google.maps.LatLng(0, 0),
mapTypeId : google.maps.MapTypeId.ROADMAP
};
// create map
var map = new google.maps.Map( $el[0], args);
// add a markers reference
map.markers = [];
// add markers
$markers.each(function(){
add_marker( $(this), map );
});
// center map
center_map( map );
}
/*
* add_marker
*
* This function will add a marker to the selected Google Map
*
* @type function
* @date 8/11/2013
* @since 4.3.0
*
* @param $marker (jQuery element)
* @param map (Google Map object)
* @return n/a
*/
function add_marker( $marker, map ) {
// var
var latlng = new google.maps.LatLng( $marker.attr('data-lat'), $marker.attr('data-lng') );
// create marker
var marker = new google.maps.Marker({
position : latlng,
map : map
});
// add to array
map.markers.push( marker );
// if marker contains HTML, add it to an infoWindow
if( $marker.html() )
{
// create info window
var infowindow = new google.maps.InfoWindow({
content : $marker.html()
});
// show info window when marker is clicked
google.maps.event.addListener(marker, 'click', function() {
infowindow.open( map, marker );
});
}
}
/*
* center_map
*
* This function will center the map, showing all markers attached to this map
*
* @type function
* @date 8/11/2013
* @since 4.3.0
*
* @param map (Google Map object)
* @return n/a
*/
function center_map( map ) {
// vars
var bounds = new google.maps.LatLngBounds();
// loop through all markers and create bounds
$.each( map.markers, function( i, marker ){
var latlng = new google.maps.LatLng( marker.position.lat(), marker.position.lng() );
bounds.extend( latlng );
});
// only 1 marker?
if( map.markers.length == 1 )
{
// set center of map
map.setCenter( bounds.getCenter() );
map.setZoom( 16 );
}
else
{
// fit to bounds
map.fitBounds( bounds );
}
}
/*
* document ready
*
* This function will render each map when the document is ready (page has loaded)
*
* @type function
* @date 8/11/2013
* @since 5.0.0
*
* @param n/a
* @return n/a
*/
$(document).ready(function(){
$('.acf-map').each(function(){
render_map( $(this) );
});
});
})(jQuery);
Save that file in your theme folder, and name it google-maps.js or something similar. In my theme, all scripts are in the library/js folder.
Step 3
Now you need to add the scripts to your template. You can paste the link in the header of your template, but that’s not a very good practice; it’s much better to add them via wp_enqueue_script()
.
In your functions.php file, add the following code:
function my_theme_add_scripts() {
wp_enqueue_script( 'google-map', 'https://maps.googleapis.com/maps/api/js?key=XXXXX', array(), '3', true );
wp_enqueue_script( 'google-map-init', get_template_directory_uri() . '/library/js/google-maps.js', array('google-map', 'jquery'), '0.1', true );
}
add_action( 'wp_enqueue_scripts', 'my_theme_add_scripts' );
function my_acf_google_map_api( $api ){
$api['key'] = 'XXXX';
return $api;
}
add_filter('acf/fields/google_map/api', 'my_acf_google_map_api');
On lines 2 and 10, replace “XXXX” for your Google Map API Key.
On line 3, make sure that the path to the script points to where you saved the file in step 2.
Step 3 – optional
If you only want to load your map in certain page, for example, the “Contact” page, you can modify the code above like this:
function my_theme_add_scripts() {
if (is_page('contact')) {
wp_enqueue_script( 'google-map', 'https://maps.googleapis.com/maps/api/js?key="XXXX', array(), '3', true );
wp_enqueue_script( 'google-map-init', get_template_directory_uri() . '/library/js/google-maps.js', array('google-map', 'jquery'), '0.1', true );
}
}
add_action( 'wp_enqueue_scripts', 'my_theme_add_scripts' );
This way, the scripts won’t be loaded in other pages, where they are not necessary.
Step 4
On the template where you want to add the map, add the following code inside the loop:
<?php
$location = get_field('location');
if( !empty($location) ):
?>
<div class="acf-map">
<div class="marker" data-lat="<?php echo $location['lat']; ?>" data-lng="<?php echo $location['lng']; ?>"></div>
</div>
<?php endif; ?>
Make sure that you change the name ‘location‘ in get_field('location');
to match the name of your custom field.
That’s it. Your map should be showing, along with the location selected.
Hi Alicia, I’ve been searching everywhere for a post like this – so thanks for that. However, I am still having trouble with this even after following these instructions. Would it be possible to get some assistance or advice from you. Thanks
It would be best to post your code, or link in StackOverflow. I can’t really help without looking at your code.
This is great Alicia! Soooo much easier to understand than anything else I’ve read. I’m trying to display maps as sub fields of a repeater field and switched the the_field tags for the_sub_field and it’s not working for me. Any idea if there is anything else I would need to tweak?
Sorry, but I’m not that familiar with the repeater fields. I do know that the code I posted will only show one marker. If you go to the ACF site, they do have an alternate sample JS for multiple markers. That may help.
Hi Alicia
Great post, helped this novice out! I got some errors when folloowing this out and after some google-fu realised you cant have ‘-‘ in function names. Changing
“function my-theme_add_scripts() {” to “function my_theme_add_scripts() {”
and
“add_action( ‘wp_enqueue_scripts’, ‘my-theme_add_scripts’ );” to “add_action( ‘wp_enqueue_scripts’, ‘my_theme_add_scripts’ );”
Did the trick.
Thank you so much!!!! it was messing everything up with the hyphen. Works like a charm now with the underscores. Saved myself some work, thank you both.
Hi there, I am interested in posting google map/calendar/etc fields from my front-end for guest users. From this post and the ACF documentation page I gather that there is no front-end form for any of the ACF specific types, or am I missing something?
ACF is meant to add custom fields to post, pages, and custom post types. So, for example, you can add a map to your contact page. To add a Google map so that people can manipulate it in the front end, you’d need a different solution.
Thanks Alicia for this great article. It’s working but I encountered a problem. It’s showing selected location but the location is not visible because it is being covered by sea and islands- howland island, baker island etc.., please help me.
You could try setting a different zoom factor. You can adjust the zoom in the code in step 2, line 23. You can also check Google Map documentation.
Thanks Alicia, now I get solved. zoom factor was not the issue, actually I had made mistake with wp_enqueue_script() function.
I’ve got this working on one of my site but another it doesn’t seem to work and I don’t see any javascript or php errors…
Are you able to assist?
It would be best if you post your code in StackOverflow.
This worked great, just wanted to say thanks!
Thanks you, a lot easier to understand. Just to mention that if you rename map container, the map will not render. So, keep .acf-map as it is.
Hello Alicia,
I have another scenario if you would be able to assist please.
I need to loop through a repeater (offices repeater) that has a google map field.
I want to display the offices info and a link “view google map” that will open that specific map into a bootstrap modal.
any idea how to assist me ? many thanks in advance.
Sorry, but I have no experience with repeater fields. Have you checked the documentation?
Thank you very much for this. The ACF website indeed does not explain things very cleary, but you did! I got it to work thanks to your explanation. Thank you!
Thanks for the great tutorial!
I’ve followed the instructions here but all I’m getting is a blank box with a border and nothing in it? Can you help not sure what is going wrong. Thanks
It’s hard to tell without looking at your code. The most common error is not changing the name ‘location’ in
get_field('location');
to match your custom field in step 4. It that’s not the issue. I’d recommend posting your code in StackOverflow.Heres my code. I named my field map in ACF. All I’m seeing is a box with a grey border.
Opps didn’t seem to work
Heres a screen grab of my code. I named my field ‘map’ in ACF so I did update location correctly. All I’m seeing on the front end is a box with a grey border.
If it is loading the correct field, the problem may be that the scripts aren’t loading, or that there is no map to show (there are no markers in the map in the page or post you are trying to show).
Use the developer tools in your browser to troubleshoot where the problem is. Once you have narrowed down the problem, please post your code in StackOverflow. This isn’t a troubleshooting forum, SO is. You’ll probably get better help, from multiple people there.
Thank you great tutorial keep it up