ACF Google Map using WordPress Gutenberg Editor
Create a Block called Maps
Maps – init.php
<?php
/*
* Maps block
*
* @var $block WP_Block
**/
/*
* Register block
**/
acf_register_block_type(
array(
'render_callback' => 'render_block_maps',
'name' => 'maps',
'title' => __( 'Maps', 'nucleo' ),
'category' => 'nucleo',
'mode' => 'preview',
'supports' => array(
'align' => array( 'wide' ),
'anchor' => true,
'mode' => false,
'jsx' => true,
),
)
);
/*
* Render block
*
* @param array $block The block settings and attributes.
* @param string $content The block inner HTML (empty).
* @param bool $is_preview True during AJAX preview.
* @param (int|string) $post_id The post ID this block is saved to.
**/
function render_block_maps( $block, $content = '', $is_preview = false, $post_id = 0 ) {
$classes = 'wp-block-maps';
$uploads = wp_upload_dir();
$rows = get_field("branches", "options"); ?>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBmQ4Hy6t0pp_Wq3qj4yMwMAMQ2H6qZSY4"></script>
<div class="<?php echo nucleo_block_classes( $classes, $block['className'] ); ?> alignfull">
<div class="row sidebar-row">
<div class="col-lg-4 sidebar-col">
<div class="intro-container bg-primary text-white">
<div class="intro bg-primary">
<?php echo '<InnerBlocks/>'; ?>
</div>
<?php if( $rows ) { ?>
<?php foreach( $rows as $row ) {
$name = $row['name'];
$str = strtolower($name);
$phone = $row['phone'];
$fax = $row['fax'];
$email = $row['email'];
$address = $row['address'];
$open_times = $row['open_times'];
$other_opening_hours = $row['other_opening_hours'];?>
<div id="map_<?php echo str_replace(' ', '', $str); ?>" class="map-details text-white">
<?php if(!empty($name)): ?>
<h3><?php echo $name; ?></h3>
<?php endif; ?>
<?php if(!empty($address)): ?>
<p class="address"><?php echo $address; ?></p>
<?php endif; ?>
<?php if(!empty($phone)): ?>
<p>Phone: <a href="tel:<?php echo preg_replace('/\D+/', '', $phone); ?>"><?php echo $phone; ?></a></p>
<?php endif; ?>
<?php if(!empty($fax)): ?>
<p>Fax: <a href="tel:<?php echo preg_replace('/\D+/', '', $fax); ?>"><?php echo $fax; ?></a></p>
<?php endif; ?>
<?php if(!empty($email)): ?>
<p>Email: <a href="mailto:<?php echo $email; ?>"><?php echo $email; ?></a></p>
<?php endif; ?>
<?php if(!empty($open_times)): ?>
<p class="hours">Opening Hours:<br/>
<?php echo $open_times; ?></p>
<?php endif; ?>
<?php if(!empty($other_opening_hours)): ?>
<p><?php echo $other_opening_hours; ?></p>
<?php endif; ?>
</div>
<?php } ?>
<?php } ?>
</div>
</div>
<div class="col-lg-8 map-col">
<?php if( $rows ) { ?>
<div class="nbgm-map">
<?php foreach( $rows as $row ) {
$name = $row['name'];
$str = strtolower($name);
$_markers = $row['map_marker']; ?>
<div class="marker" data-lat="<?php echo $_markers['lat']; ?>" data-lng="<?php echo $_markers['lng']; ?>" data-img="<?php echo esc_url( $uploads['baseurl']); ?>/map_marker.png" data-marker="#map_<?php echo str_replace(' ', '', $str); ?>"></div>
<?php } ?>
</div>
<?php } ?>
</div>
</div>
</div>
<?php echo $output;
}
Get Your Google Map API
In order use of the Google Map ACF Field, you must first register a valid API key.
Get a Google API Map Key – click on Get a Key
Once you have the API Key add it via your functions.php by using this code below, replace “xxxxxxx” with your actual Key.
// ACF Google Map
function my_acf_google_map_api( $api ){
$api['key'] = 'xxxxxxx';
return $api;
}
add_filter('acf/fields/google_map/api', 'my_acf_google_map_api');
Now that the Google API key is activated, fields need to be populated.
Add details
On this particular website it uses a repeater field in the options Page.

Add JS Code
(function ($) {
// generate map
function new_map($el) {
// var
var $markers = $el.find('.marker');
// vars
var args = {
zoom: 20,
center: new google.maps.LatLng(0, 0),
disableDefaultUI: true,
mapTypeId: google.maps.MapTypeId.ROADMAP,
styles: [{"featureType":"all","elementType":"geometry.fill","stylers":[{"weight":"2.00"}]},{"featureType":"all","elementType":"geometry.stroke","stylers":[{"color":"#9c9c9c"}]},{"featureType":"all","elementType":"labels.text","stylers":[{"visibility":"on"}]},{"featureType":"landscape","elementType":"all","stylers":[{"color":"#f2f2f2"}]},{"featureType":"landscape","elementType":"geometry.fill","stylers":[{"color":"#ffffff"}]},{"featureType":"landscape.man_made","elementType":"geometry.fill","stylers":[{"color":"#ffffff"}]},{"featureType":"poi","elementType":"all","stylers":[{"visibility":"off"}]},{"featureType":"road","elementType":"all","stylers":[{"saturation":-100},{"lightness":45}]},{"featureType":"road","elementType":"geometry.fill","stylers":[{"color":"#eeeeee"}]},{"featureType":"road","elementType":"labels.text.fill","stylers":[{"color":"#7b7b7b"}]},{"featureType":"road","elementType":"labels.text.stroke","stylers":[{"color":"#ffffff"}]},{"featureType":"road.highway","elementType":"all","stylers":[{"visibility":"simplified"}]},{"featureType":"road.arterial","elementType":"labels.icon","stylers":[{"visibility":"off"}]},{"featureType":"transit","elementType":"all","stylers":[{"visibility":"off"}]},{"featureType":"water","elementType":"all","stylers":[{"color":"#46bcec"},{"visibility":"on"}]},{"featureType":"water","elementType":"geometry.fill","stylers":[{"color":"#c8d7d4"}]},{"featureType":"water","elementType":"labels.text.fill","stylers":[{"color":"#070707"}]},{"featureType":"water","elementType":"labels.text.stroke","stylers":[{"color":"#ffffff"}]}],
};
// 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);
return map;
}
// add the marker
function add_marker($marker, map) {
// var
var latlng = new google.maps.LatLng($marker.attr('data-lat'), $marker.attr('data-lng'));
var icon = {
url: $marker.attr('data-img'),
scaledSize: new google.maps.Size(30.19, 40.25)
};
// create marker
var marker = new google.maps.Marker({
position: latlng,
icon: icon,
map: map
});
// add to array
map.markers.push(marker);
map.active_window = false;
var myId = $marker.attr('data-marker');
// show info window when marker is clicked
google.maps.event.addListener(marker, 'click', function() {
$('.map-details').removeClass( "active" );
$('.intro').removeClass( "d-none" );
for (var i = 0; i < map.markers.length; i++) {
map.markers[i].setIcon({
url: $marker.attr('data-img'),
scaledSize: new google.maps.Size(30.19, 40.25)
});
}
// create marker
if($(myId).hasClass("active")){
$(myId).removeClass( "active" );
$('.intro').removeClass( "d-none" );
}else{
$(myId).addClass("active");
$('.intro').addClass( "d-none" );
this.setIcon({
url: $marker.attr('data-img'),
scaledSize: new google.maps.Size(60.37, 80.5)
});
}
});
$(document).on('click', '.sidebar-col', function() {
$('.map-details').removeClass( "active" );
$('.intro').removeClass( "d-none" );
for (var i = 0; i < map.markers.length; i++) {
map.markers[i].setIcon({
url: $marker.attr('data-img'),
scaledSize: new google.maps.Size(30.19, 40.25)
});
}
});
}
// center the map
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(18);
} else {
// fit to bounds
map.fitBounds(bounds);
}
}
// embed it
var map = null;
$(document).ready(function() {
$('.nbgm-map').each(function() {
// create map
map = new_map($(this));
});
});
})(jQuery);
Add finally add Style _locations.scss
.wp-block-maps{
min-height: 850px;
overflow: hidden;
.row{
width: 100%;
height: 100%;
max-width: none !important;
padding: 0 !important;
@media only screen and (max-width:991px) {
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-box-orient: vertical;
-moz-box-orient: vertical;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
}
.sidebar-col{
background-color: $secondary;
min-height: 850px;
padding: 5rem 6.25rem;
@media only screen and (max-width: 1439px) {
padding: 5rem 4rem;
}
@media only screen and (max-width:991px) {
min-height: 450px;
-webkit-box-ordinal-group: 2;
-moz-box-ordinal-group: 2;
-ms-flex-order: 2;
-webkit-order: 2;
order: 2;
}
.intro-container{
position: relative;
.intro{
position:absolute;
padding: 2.5rem 2.5rem 3rem 2.5rem;
@media only screen and (max-width: 1439px) {
padding: 2.5rem 2rem 3rem 2rem;
}
@media only screen and (max-width:950px) {
}
@media only screen and (max-width:767px) {
padding: 2.5rem 1rem 3rem 1rem;
}
h3{
font-size: 1.875rem;
}
p{
font-size: $font-size-md;
&:last-child{
margin-bottom: 0;
}
}
}
.map-details{
background-color: #4781D1;
padding: 0 2.5rem 0 2.5rem;
position: relative;
z-index: 99;
width: 100%;
height: 0;
transition: all 0.3s ease;
@media only screen and (max-width:767px) {
padding: 0 1rem 0 1rem;
}
h3{
margin-bottom: 1rem;
opacity: 0;
transition: all 0.3s ease;
}
p{
margin: 0;
font-size: $font-size-md;
opacity: 0;
transition: all 0.3s ease;
@media only screen and (max-width: 1300px) {
font-size:0.875rem;
}
@media only screen and (max-width:991px) {
font-size: $font-size-md;
}
&.address{
margin-bottom: 1rem;
}
&.hours{
margin: 1rem 0;
}
a{
color: inherit;
}
}
&:before{
content: "";
width: 0;
height: 0;
border-top: 12.5px solid transparent;
border-bottom: 12.5px solid transparent;
position: absolute;
z-index: 1;
top: 3rem;
opacity: 0;
left: 0;
border-right: 25px solid #fff;
transition: all 0.3s ease;
}
&.active{
padding: 2.5rem 2.5rem 3rem 2.5rem;
@media only screen and (max-width: 1439px) {
padding: 2.5rem 2rem 3rem 2rem;
}
height: auto;
min-height: 100%;
&:before{
left: -3rem;
opacity: 1;
}
h3,p{
opacity: 1;
}
}
}
}
&:after{
content: "";
width: 0;
height: 0;
border-top: 85px solid transparent;
border-bottom: 85px solid transparent;
position: absolute;
top: 5rem;
right: -145px;
z-index: 9;
border-left: 145px solid $secondary;
}
}
.map-col{
min-height: 850px;
height: 100%;
padding: 0;
@media only screen and (max-width:991px) {
min-height: 500px;
-webkit-box-ordinal-group: 1;
-moz-box-ordinal-group: 1;
-ms-flex-order: 1;
-webkit-order: 1;
order: 1;
}
@media only screen and (max-width:767px) {
min-height: 400px;
}
.nbgm-map {
width: 100%;
height: 850px;
@media only screen and (max-width:991px) {
height: 500px;
}
@media only screen and (max-width:767px) {
height: 400px;
}
}
// Fixes potential theme css conflict.
.nbgm-map img {
max-width: inherit !important;
cursor: default !important;
}
}
}
}
Finally the page would look like this:
