緯度・経度から本文下にGoogleマップを表示する方法

Cocoonカスタマイズ集
この記事は約7分で読めます。
記事内に広告が含まれています。

はじめに

Googleマップを埋め込むには、埋め込みコードを取得して「カスタムHTML」ブロックに貼り付ける必要があります。

しかし、この方法では毎回コードをコピー&ペーストする手間がかかり、店舗情報の更新や管理が煩雑になりがちです。

そこで、カスタム投稿タイプを使えば、店舗情報を整理して管理できます。
さらに、緯度・経度を入力するだけで、記事本文の下に自動的にGoogleマップを表示することが可能です。

この記事では、この方法について説明します。

完成イメージ

実装手順

以下のコードをfunctions.phpに追加します。

// カスタム投稿タイプを追加
add_action('init', function () {
  register_post_type('my_shop', [
    'labels'       => ['name' => '店舗'],
    'public'       => true,
    'has_archive'  => true,
    'menu_icon'    => 'dashicons-location',
    'supports'     => ['title', 'editor', 'thumbnail'],
    'show_in_rest' => true,
  ]);
});


// メタボックスを追加
add_action('add_meta_boxes', function () {
  add_meta_box(
    'shop',
    '位置情報',
    'redeer_shop',
    'my_shop',
    'side'
  );
});


/**
 * メタボックスの入力フォームを出力
 *
 * @param WP_Post $post 投稿オブジェクト
 * @return void
 */
if (!function_exists('redeer_shop')):
function redeer_shop($post) {
  // 既存値を取得
  $coords = get_post_meta($post->ID, 'my_shop_coords', true);

  wp_nonce_field('shop_action', 'shop_nonce');
  ?>
  <p>緯度,経度(例: 35.681236,139.767125)</p>
  <input type="text" name="my_shop_coords" value="<?= esc_attr($coords); ?>" style="width: 100%;">
  <?php
}
endif;


// 投稿データを保存
add_action('save_post', function ($id) {
  // nonceチェック
  if (!isset($_POST['shop_nonce']) || !wp_verify_nonce($_POST['shop_nonce'], 'shop_action')) {
    return;
  }

  // 自動保存チェック
  if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
    return;
  }

  // リビジョンは除外
  if (wp_is_post_revision($id)) {
    return;
  }

  // 権限チェック
  if (!current_user_can('edit_post', $id)) {
    return;
  }

  if (isset($_POST['my_shop_coords'])) {
    update_post_meta($id, 'my_shop_coords', sanitize_text_field($_POST['my_shop_coords']));
  } else {
    delete_post_meta($id, 'my_shop_coords');
  }
});


// 本文を変更
add_filter('the_content', function ($content) {
  if (!is_singular('my_shop') || !is_main_query()) {
    return $content;
  }

  // カスタムフィールドを取得
  $coords = get_post_meta(get_the_ID(), 'my_shop_coords', true);

  if (!$coords || !str_contains($coords, ',')) {
    return $content;
  }

  // 緯度,経度に分解
  [$lat, $lng] = array_map('floatval', explode(',', $coords));

  // Googleマップ埋め込み
  ob_start();
  ?>
  <div style="margin-top:24px;">
    <iframe width="100%" height="360" style="border:0;border-radius:12px" loading="lazy" allowfullscreen referrerpolicy="no-referrer-when-downgrade" src="https://www.google.com/maps?q=<?= $lat; ?>,<?= $lng; ?>&hl=ja&z=16&output=embed"></iframe>
  </div>
  <?php

  return $content . ob_get_clean();
});

参考:Leafletを使ったマップ表示例

Googleマップ埋め込みコードを、ライブラリ「Leaflet+OpenStreetMap」を使ったマップ表示に置き換えます。
LeafletならAPIキー不要で、ピンの上にリンクやポップアップも自由に追加できます。

完成イメージ

実装手順

以下のコードに変更します。

add_filter('the_content', function ($content) {
  if (!is_singular('my_shop') || !is_main_query()) {
    return $content;
  }

  // カスタムフィールドを取得
  $coords = get_post_meta(get_the_ID(), 'my_shop_coords', true);

  if (!$coords || !strpos($coords, ',')) {
    return $content;
  }

  // 緯度,経度に分解
  [$lat, $lng] = array_map('floatval', explode(',', $coords));

  // マップ用のHTMLとLeafletスクリプト
  ob_start();
  ?>
  <div id="leaflet-map" style="width:100%; height:360px;"></div>
  <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
  <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>

  <script>
  /**
   * Leafletマップの初期化とマーカー設置
   *
   * @return {void}
   */
  document.addEventListener("DOMContentLoaded", function () {
    var map = L.map('leaflet-map').setView([<?= $lat; ?>, <?= $lng; ?>], 16);

    // OSMタイルを読み込み
    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
      attribution: '© OpenStreetMap contributors'
    }).addTo(map);

    // マーカー設置
    L.marker([<?= $lat; ?>, <?= $lng; ?>])
      .addTo(map)
      .bindPopup('<a href="' + window.location.href + '">店舗ページを見る</a>');
  });
  </script>
  <?php

  return $content . ob_get_clean();
});

上記コードのJavaScript内にあるbindPopup()では、Leafletの機能としてマーカー(ピン)クリック時にリンク付きポップアップを表示できます。

なお、今回のサンプルコードではURLにwindow.location.hrefを指定しているため、現在表示しているページ自身へのリンクとなっています。
一覧ページや共通マップ等で利用する場合は、該当する各詳細ページのURLに書き換えてご活用ください。

さいごに

今回紹介した方法を使えば、カスタム投稿タイプで店舗情報を簡単に管理でき、緯度・経度を入力するだけで本文下にマップを自動表示できます。
さらにLeafletを使えば、APIキー不要でマーカーにリンクやポップアップを自由に追加可能です。

タイトルとURLをコピーしました