ACFとGoogle Map

クライアントのホームページでアドバンスド カスタム フィールド(ACF)を使ってます。今回デザイン変更に伴い、ACFとGoogle Mapを再設定することになりました。

以下、忘備録として、必要な作業を書き出しておきます。

Google Mapの設定

Google Map ですが、2018年7月の有料化に伴い、ACFの様にAPIを使ってデータのやりとりをする場合は、設定が少しややこしくなりました。

ゼロからやる場合は、次の様な手順が必要となります。

  1. Google Cloud Consoleで支払い設定
  2. プロジェクト作成
  3. API KEYを取得
  4. 複数のMAP APIを有効化
    • Maps JavaScript API
    • Geocoding API
    • Geolocation API
    • Directions API
    • Distance Matrix API
    • Maps Elevation API
    • Maps Embed API
    • Maps Static API
    • Places API

ACFの設定

  1. JavaScriptの読み込み
    1. <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=YOUR-API-KEY"></script>
      
      <script type="text/javascript">
      (function( $ ) {
      
      /**
       * initMap
       *
       * Renders a Google Map onto the selected jQuery element
       *
       * @date    22/10/19
       * @since   5.8.6
       *
       * @param   jQuery $el The jQuery element.
       * @return  object The map instance.
       */
      function initMap( $el ) {
      
          // Find marker elements within map.
          var $markers = $el.find('.marker');
      
          // Create gerenic map.
          var mapArgs = {
              zoom        : $el.data('zoom') || 16,
              mapTypeId   : google.maps.MapTypeId.ROADMAP
          };
          var map = new google.maps.Map( $el[0], mapArgs );
      
          // Add markers.
          map.markers = [];
          $markers.each(function(){
              initMarker( $(this), map );
          });
      
          // Center map based on markers.
          centerMap( map );
      
          // Return map instance.
          return map;
      }
      
      /**
       * initMarker
       *
       * Creates a marker for the given jQuery element and map.
       *
       * @date    22/10/19
       * @since   5.8.6
       *
       * @param   jQuery $el The jQuery element.
       * @param   object The map instance.
       * @return  object The marker instance.
       */
      function initMarker( $marker, map ) {
      
          // Get position from marker.
          var lat = $marker.data('lat');
          var lng = $marker.data('lng');
          var latLng = {
              lat: parseFloat( lat ),
              lng: parseFloat( lng )
          };
      
          // Create marker instance.
          var marker = new google.maps.Marker({
              position : latLng,
              map: map
          });
      
          // Append to reference for later use.
          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 );
              });
          }
      }
      
      /**
       * centerMap
       *
       * Centers the map showing all markers in view.
       *
       * @date    22/10/19
       * @since   5.8.6
       *
       * @param   object The map instance.
       * @return  void
       */
      function centerMap( map ) {
      
          // Create map boundaries from all map markers.
          var bounds = new google.maps.LatLngBounds();
          map.markers.forEach(function( marker ){
              bounds.extend({
                  lat: marker.position.lat(),
                  lng: marker.position.lng()
              });
          });
      
          // Case: Single marker.
          if( map.markers.length == 1 ){
              map.setCenter( bounds.getCenter() );
      
          // Case: Multiple markers.
          } else{
              map.fitBounds( bounds );
          }
      }
      
      // Render maps on page load.
      $(document).ready(function(){
          $('.acf-map').each(function(){
              var map = initMap( $(this) );
          });
      });
      
      })(jQuery);
      </script>
  2. functions.phpにAPI Keyを設定
    1. function my_acf_google_map_api( $api ){
          $api['key'] = 'YOUR-API-KEY';
          return $api;
      }
      add_filter('acf/fields/google_map/api', 'my_acf_google_map_api');
  3. 地図書き出し部分へのコード追加
    1. <?php 
      $location = get_field('location');
      if( $location ): ?>
          <div class="acf-map" data-zoom="16">
              <div class="marker" data-lat="<?php echo esc_attr($location['lat']); ?>" data-lng="<?php echo esc_attr($location['lng']); ?>"></div>
          </div>
      <?php endif; ?>
  4. CSS書き込み
    1. .acf-map {
          width: 100%;
          height: 400px;
          border: #ccc solid 1px;
          margin: 20px 0;
      }
      
      // Fixes potential theme css conflict.
      .acf-map img {
         max-width: inherit !important;
      }