Advertisement
Advertisement

More Related Content

Slideshows for you(20)

Viewers also liked(20)

Advertisement

More from Hidekazu Ishikawa(20)

Advertisement

WordPressと外部APIとの連携

  1. WordPressと外部APIとの連携 「お城めぐりGPSスタンプラリー・戦国攻城記」サイトの裏側
  2. 自己紹介
  3. 名古屋で株式会社ベクトル というウェブ制作会社をしています。 普段はWordPressを使って企業サイトなどを制作しながら生きています。 デザイナー上がりなので高度なPGやサーバー・DBなど、バックエンドの 部分は苦手です… 名前:石川栄和 Twitter : @kurudrive 2013 WordCampTokyo セッションパネラー 2013 WordFesNagoya セッションスピーカー 2013 WordCrab Fukui セッションスピーカー 2012 WordCamp Tokyo セッションスピーカー その他セミナーやLTも少し… 最近のWordPressコミュニティでの活動
  4. 書籍 いちばんやさしい WordPress の教本 人気講師が教える本格Webサイトの作り方 現場でかならず使われている WordPressデザインのメソッド
  5. テーマ作ってます bizvektor.com
  6. お城めぐりGPSスタンプラリー
  7. WordPressで出来てます。
  8. GeolocationAPIとの連携(1) 今いる場所から近い順に並べて表示する
  9. 紹介するGeolocationAPIの活用例1 位置情報を取得して、 今いる場所から近い順に 表示する。
  10. 処理概要 ボタンを押したら位置情報を取得 1 2 取得した位置情報をURLに くっつけて近くのお城一覧ページへ 移動 http://kojoki.jp/nearby/?lat=緯度&lng=経度
  11. 処理概要 URLに付いた位置情報を 受け取る 3 4 DBからお城のデータを全件取得 5 位置情報が近い順に並び替えて 表示する
  12. 位置情報を扱う機能を作る前に この投稿データを位置情報と連携して使用するので、 カスタムフィールドに緯度・経度を登録します。 各お城の情報の作成 投稿又はカスタム投稿タイプに お城の写真や説明文などと共に 登録。
  13. 処理概要 ボタンを押したら位置情報を取得 1 2 取得した位置情報をURLにくっつけて 近くのお城一覧ページ(固定ページ)へ移動 URLに付いた位置情報を受け取る 3 4 DBからお城のデータを全件取得 5 位置情報が近い順に並び替えて表示する
  14. ユーザーの位置情報を取得するトリガー <a href =“#” id=“nearbyBtn”> 近くのお城を探す </a> Jsファイルへの記述 // ボタンがクリックされたら jQuery('a#nearbyBtn').click(function(){ // 位置情報取得の処理を実行 get_gps(); }); ここで位置情報取得の処理をする。 詳細は次へ…
  15. 位置情報を取得するjs function get_gps(){ if (navigator.geolocation) { // Geolocationが使える場合 // 現在の位置情報を取得 navigator.geolocation.getCurrentPosition( // (1)位置情報取得に成功したとき function (position) { lat = position.coords.latitude; lng = position.coords.longitude; location.href=" /nearby/?lat=" + lat + "&lng=" + lng; }, // (2)位置情報の取得に失敗した場合 function (error) { window.alert("位置情報の取得ができませんでした。"); } // function (error) ); } else { // Geolocationが使えない場合 window.alert("このブラウザでは位置情報が取得出来ないためご利用できません。"); } } // get_gps
  16. 取得した位置情報元に移動 function get_gps(){ if (navigator.geolocation) { // Geolocationが使える場合 // 現在の位置情報を取得 navigator.geolocation.getCurrentPosition( // (1)位置情報取得に成功したとき function (position) { lat = position.coords.latitude; lng = position.coords.longitude; location.href=" /nearby/?lat=" + lat + "&lng=" + lng; }, // (2)位置情報の取得に失敗した場合 function (error) { window.alert("位置情報の取得ができませんでした。"); } // function (error) ); } else { // Geolocationが使えない場合 window.alert("このブラウザでは位置情報が取得出来ないためご利用できません。"); } } // get_gps 緯度 経度 近くのお城一覧用固定ページ (スラッグ:nearby)へ移動。 その際に取得した緯度経度情報を パラメーターとしてくっつける。 http://kojoki.jp/nearby/?lat=35.164844099999996&lng=136.8965278
  17. Jsファルに記述するサンプルコード jQuery(document).ready(function(jQuery){ function get_gps(){ if (navigator.geolocation) { // Geolocationが使える場合 // 現在の位置情報を取得 navigator.geolocation.getCurrentPosition( // (1)位置情報取得に成功したとき function (position) { lat= position.coords.latitude; lng= position.coords.longitude; location.href=" /nearby/?lat=" + lat + "&lng=" + lng; }, // (2)位置情報の取得に失敗した場合 function (error) { window.alert("位置情報の取得ができませんでした。"); } // function (error) ); } else { // Geolocationが使えない場合 window.alert("このブラウザでは位置情報が取得出来ないためご利用できません。"); } } // get_gps // ボタンがクリックされたら jQuery('a#nearbyBtn').click(function(){ // 位置情報取得の処理を実行 get_gps(); }); }); この記述をしているjsファイル自体の読み込み場所に よっては不要
  18. 処理概要 ボタンを押したら位置情報を取得 1 2 取得した位置情報をURLにくっつけて 近くのお城一覧ページ(固定ページ)へ移動 URLに付いた位置情報を受け取る 3 4 DBからお城のデータを全件取得 5 位置情報が近い順に並び替えて表示する
  19. お城一覧用ページで位置情報を受け取る 近くのお城一覧ページ用のテンプレートファイルで URLについている位置情報を受け取る <?php // パラメターから位置情報を取得 $lat = (isset($_GET['lat'])) ? esc_html($_GET['lat']) : ''; $lng = (isset($_GET['lng'])) ? esc_html($_GET['lng']) : ''; ?> http://kojoki.jp/nearby/?lat=緯度&lng=経度
  20. 処理概要 ボタンを押したら位置情報を取得 1 2 取得した位置情報をURLにくっつけて 近くのお城一覧ページ(固定ページ)へ移動 URLに付いた位置情報を受け取る 3 4 DBからお城のデータを全件取得 5 位置情報が近い順に並び替えて表示する
  21. 登録されているお城情報を取得 データベースに登録されているお城の情報(投稿 データ)をとりあえず全件取得して、 $spot_items に入れます。 /*-------------------------------------------*/ /* 現在登録されている城情報を全て取得 /*-------------------------------------------*/ $spot_items = get_posts( array( ‘post_type’ => ‘post’, // お城情報が入っている投稿タイプ ‘posts_per_page’ => -1, // 全件 ) );
  22. 処理概要 ボタンを押したら位置情報を取得 1 2 取得した位置情報をURLにくっつけて 近くのお城一覧ページ(固定ページ)へ移動 URLに付いた位置情報を受け取る 3 4 DBからお城のデータを全件取得 5 位置情報が近い順に並び替えて表示する
  23. 取得したお城情報に距離情報を追加したい Array ( [0] => WP_Post Object ( [ID] => 001 [post_title] => 名古屋城 (以下略) [distance] => (距離の数値) ) [1] => WP_Post Object ( [ID] => 002 [post_title] => 清洲城 投稿ID 投稿タイトル 距離で並べ替えるために こんな感じで距離の情報を 追加したい 取得したお城情報 $spot_items の中身
  24. 現在地との距離を算出して追加 foreach ($spot_items as $key => $spot_item) { // カスタムフィールドから緯度経度情報を取得 $spotLat = get_post_meta($spot_item->ID,'Map_lat',true); $spotLng = get_post_meta($spot_item->ID,'Map_lng',true); if (($spotLat) && ($spotLng)) { // 現在地からの距離の算出 $distanceLat = $spotLat - $lat; $distanceLng = $spotLng - $lng; $distance = sqrt(pow($distanceLat,2)+pow($distanceLng,2)); // 並び替え用の数値として距離「distance」を追加 $spot_items[$key]->distance = $distance; } } ※本当は地球の「丸さ」を 考慮した計算式の方が良い
  25. お城情報の並び替え /* 距離で並び替えるという比較関数を定義 /*-------------------------------------------*/ function itemsort_by_distance( $a , $b ){ //距離を比較 $spot_items = strcmp( $a->distance , $b->distance ); return $spot_items; } /* 比較関数に書いたルールで並び替え /*-------------------------------------------*/ usort( $spot_items , "itemsort_by_distance" );
  26. 並び替えたデータの出力 foreach ($spot_items as $key => $post) { the_title(); echo '<br />'; } wp_reset_postdata(); 近い順に並んだお城情報 $spot_items を ループして順番に表示する。
  27. サンプルソース /*-------------------------------------------*/ /* URLのパラメター(緯度と経度の位置情報)を取得 /*-------------------------------------------*/ $lat = (isset($_GET['lat'])) ? esc_html($_GET['lat']) : ''; $lng = (isset($_GET['lng'])) ? esc_html($_GET['lng']) : ''; /*-------------------------------------------*/ /* 距離チェック /*-------------------------------------------*/ /* 現在登録されている城情報を全て取得 /*-------------------------------------------*/ $spot_items = get_posts( array( 'post_type' => 'post', // カスタム投稿タイプチェックイン 'posts_per_page' => -1, // 全件 ) ); /* 各お城情報について、現在地からの距離を算出してデータに追加 /*-------------------------------------------*/ foreach ($spot_items as $key => $spot_item) { $spotLat = get_post_meta($spot_item->ID,'Map_lat',true); $spotLng = get_post_meta($spot_item->ID,'Map_lng',true); if (($spotLat) && ($spotLng)) { $distanceLat = $spotLat - $lat; $distanceLng = $spotLng - $lng; // 距離の算出 pow = 乗算 / sqrt = 平方根 $distance = sqrt(pow( $distanceLat ,2) + pow( $distanceLng ,2)); // 並び替え用の数値として距離「distance」を追加 $spot_items[$key]->distance = $distance; } } /* 距離で並び替えるという比較関数を定義 /*-------------------------------------------*/ function itemsort_by_distance( $a , $b){ //距離を比較 $spot_items = strcmp( $a->distance , $b->distance ); return $spot_items; } /* 比較関数にそって並び替え /*-------------------------------------------*/ usort( $spot_items , "itemsort_by_distance" ); /*-------------------------------------------*/ /* 並び替えた城情報を出力 /*-------------------------------------------*/ foreach ($spot_items as $key => $post) { the_title(); echo '<br />'; } wp_reset_postdata();
  28. GeolocationAPIとの連携(2) チェックインの判定と保存処理
  29. 処理概要 各お城の詳細ページでチェックイン ボタンを押したら位置情報を取得 1 2 お城の位置情報と、取得した位置 情報を比較して判定。 3 チェックイン成功だったら そのデータを保存する。
  30. チェックインの判定 位置情報を取得して対象と近いか判定
  31. お城詳細画面のチェックインボタン 未ログイン ログイン済 ログインしている時だけチェックインボタンが 表示されるようにします。
  32. ログインしていたら チェックインボタンを表示 <div id="message"></div> <div class="sectionFrame" id="checkinSection"> <?php if ( is_user_logged_in() == TRUE ) { ?> <p class="center"> <a href="#" id="checkinBtn"> 攻略の狼煙を上げる!(現地でGPSチェックイン) </a> </p> <?php } else { ?> ( ログインしていない時の表示 ) <?php } ?> </div>
  33. 位置情報の取得 <script type="text/javascript"> jQuery(document).ready(function($){ // チェックイン処理開始 jQuery('#checkinBtn').click(function(){ if (navigator.geolocation) { // Geolocationが使える場合 // 現在の位置情報を取得 navigator.geolocation.getCurrentPosition( // (1)位置情報取得に成功したとき function (position) { lat = position.coords.latitude; lng = position.coords.longitude; ここでは single.php に 直接記述 チェックインボタンが 押されたら実行 緯度 経度
  34. 位置判定用の座標生成 latMax = <?php echo esc_html(post_custom("Map_lat")) ?> + 0.015; latMin = <?php echo esc_html(post_custom("Map_lat")) ?> - 0.015; lngMax = <?php echo esc_html(post_custom("Map_lng")) ?> + 0.015; lngMin = <?php echo esc_html(post_custom("Map_lng")) ?> - 0.015; お城の位置情報をカスタムフィールド から取得して判定合格エリアの 座標生成 ( post_custom("Map_lat"),post_custom("Map_lng") )
  35. 位置判定処理 // チェックインの判定処理 if ( ( latMax > lat ) && ( lat > latMin ) && ( lngMax > lng ) && ( lng > lngMin ) ) { // チェックイン成功 } else { // チェックイン失敗 jQuery(“#message”).html(‘離れています'); } ( lat , lng ) 失敗したらボタンの上にメッセージを表示
  36. // チェックイン成功ページ(固定ページ)へ移動 location.href="<?php echo site_url(); ?>/page-checkin_post/"; 移動先の固定ページ(スラッグ:page-checkin_post/) チェックイン成功時の処理 // 判定の場合、成功したお城のID(投稿ID)をcookieに保存 // ※ あらかじめ別途 jquery.cookie.js の読み込みが必要 jQuery.cookie(“checkinSpotID”, “<?php the_ID(); ?>”, { expires: 1 , path: '/page-checkin_post/' }); チェックインしたお城の ID(投稿ID) 移動先のページでお城のIDを受け取って保存します。
  37. サンプルソース <div id="message"></div> <div class="sectionFrame" id="checkinSection"> <?php if ( is_user_logged_in() == TRUE ) { ?> <p class="center"> <a href="#" id="checkinBtn"> 攻略の狼煙を上げる!(現地でGPSチェックイン) </a> </p> <?php } else { ?> ( ログインしていない時の表示 ) <?php } ?> </div> <script type="text/javascript"> jQuery(document).ready(function($){ // チェックイン処理開始 jQuery('#checkinBtn').click(function(){ if (navigator.geolocation) { // Geolocationが使える場合 // 現在の位置情報を取得 navigator.geolocation.getCurrentPosition( // (1)位置情報取得に成功したとき function (position) { lat= position.coords.latitude; lng= position.coords.longitude; // お城の位置情報をカスタムフィールドから取得して判定合格エリアの座標生成 latMax = <?php echo esc_html(post_custom("Map_lat")) ?> + 0.015; latMin = <?php echo esc_html(post_custom("Map_lat")) ?> - 0.015; lngMax = <?php echo esc_html(post_custom("Map_lng")) ?> + 0.015; lngMin = <?php echo esc_html(post_custom("Map_lng")) ?> - 0.015; // チェックインの判定処理 if ( ( latMax > lat ) && ( lat > latMin ) && ( lngMax > lng ) && ( lng > lngMin ) ) { // 判定OK jQuery.cookie("checkinSpotID", "<?php the_ID(); ?>",{ expires: 1 , path: '/page-checkin_post/' }); // チェックイン成功ページへ移動 location.href="<?php echo site_url(); ?>/page-checkin_post/"; } else { // 判定失敗 jQuery("#message").html('離れている場合に表示するメッセージ'); } // 判定ここまで }, // (2)位置情報の取得に失敗した場合 function (error) { window.alert("位置情報の取得ができませんでした。"); } // function (error) ); } else { // Geolocationが使えない場合 window.alert("このブラウザでは位置情報が取得出来ないためご利用できません。"); } }); }); </script>
  38. チェックイン情報の保存
  39. 保存するチェックイン情報 ユーザーのチェックイン情報を保存したい。 最低限保存する情報 •チェックインしたユーザーは誰か? ログインユーザーID •チェックインしたお城はどこか? お城ページの投稿ID どこに保存するか?
  40. チェックイン情報の保存先 カスタム投稿タイプを追加して、 そこに投稿としてに保存! 最低限保存する情報 •チェックインしたユーザーIDの保存先 投稿者に設定 •チェックインしたお城ID(投稿ID)の保存先 タイトル又はカスタムフィールドに保存
  41. 保存したデータの引き出し例 $posts = get_posts(array( 'post_type' => 'checkin', 'posts_per_page' => -1, 'author' => $userID, )); ユーザーIDが $userID の人のチェックイン履歴 投稿タイプが’checkin’ 作成者が $userID 投稿者アーカイブページでも同様にユーザーの チェックイン履歴ページになる。
  42. ログインユーザーIDと チェックインしたお城のIDを取得 ログインしているユーザーID global $user_ID; get_currentuserinfo(); クッキーからチェックインした城のIDを取得 if(isset($_COOKIE["checkinSpotID"])) { $checkInId = $_COOKIE["checkinSpotID"]; } チェックイン成功ページでの処理
  43. 重複投稿チェック /*-------------------------------------------*/ /* 今日の同じ城でのチェックイン情報を取得 /*-------------------------------------------*/ $args = array( 'post_type' => 'checkin', // カスタム投稿タイプチェックイン 'orderby' => 'date', // 日付で並び替え 'order' => 'DESC', // 新着順 'posts_per_page' => 1, // 1件のみ(最新だけで良いので) 'author' => $user_ID, // 現在のログインユーザー 'meta_query' => array( // カスタムフィールドの絞り込み条件 array( 'key'=>'checkin_spot_id', 'value'=>$checkInId // 今回のチェックインIDと同じ城番号 ), ), 'date_query'=>array( array( 'year'=>date_i18n( 'Y' ), 'monthnum'=>date_i18n( 'm' ), 'day'=>date_i18n( 'd' ), ) ) ); $todayCheckinData = get_posts($args);
  44. 重複投稿チェック // 今日のGPS攻略が無い場合投稿 // (その他のパラメーターは余分な処理の実行を防止するため) if ( !$todayCheckinData && isset($checkInId) && $checkInId && $user_ID ){ /*-------------------------------------------*/ /* チェックイン情報を投稿 /*-------------------------------------------*/ } 今日同じ城でのチェックインが無い場合
  45. チェックイン情報を 投稿するためのデータを作成 $checkin_post = array(); // 投稿タイプ $checkin_post['post_type'] = 'checkin'; // 投稿の状態 $checkin_post['post_status'] = 'publish'; // 投稿のタイトル $checkin_post['post_title'] = get_the_title($checkInId); // 投稿の作成者 $checkin_post['post_author'] = $user_ID; ※お城のIDはカスタムフィールドなので別の場所で指定 タイトルはチェックインしたお城の名前
  46. チェックイン情報を投稿 $posted_ID = wp_insert_post( $checkin_post ); カスタム投稿タイプ ’checkin’ に自動で投稿 新規投稿する関数 新規投稿する情報 投稿に成功した時に、成功した投稿のIDが返ってくる カスタムフィールドにお城のIDを保存する add_post_meta($posted_ID, 'checkin_spot_id', $checkInId); 上記で成功したチェックイン情報の投稿ID 保存先のカスタムフィールドのキー チェックインしたお城ID
  47. サンプルソース // ユーザー情報を取得 global $user_ID; get_currentuserinfo(); // クッキーからチェックインした城のIDを取得 if(isset($_COOKIE["checkinSpotID"])) { $checkInId = $_COOKIE["checkinSpotID"]; } /*-------------------------------------------*/ /* 重複チェック /*-------------------------------------------*/ /* 今日の同じ城でのチェックイン情報を取得 /*-------------------------------------------*/ $args = array( 'post_type' => 'checkin', // カスタム投稿タイプチェックイン 'orderby' => 'date', // 日付で並び替え 'order' => 'DESC', // 新着順 'posts_per_page' => 1, // 1件のみ(最新だけで良いので) 'author' => $user_ID, // 現在のログインユーザー 'meta_query' => array( // カスタムフィールドの絞り込み条件 array( 'key'=>'checkin_spot_id', 'value'=>$checkInId // 今回のチェックインIDと同じ城番号 ), ), 'date_query'=>array( array( 'year'=>date_i18n( 'Y' ), 'monthnum'=>date_i18n( 'm' ), 'day'=>date_i18n( 'd' ), ) ) ); $todayCheckinData = get_posts($args); // 今日のGPS攻略が無い場合投稿(その他のパラメーターは余分な処理の実行を防止するため) if ( !$todayCheckinData && isset($checkInId) && $checkInId && $user_ID ){ /*-------------------------------------------*/ /* チェックイン情報を投稿 /*-------------------------------------------*/ // 投稿するためのデータを作成 $checkin_post = array(); $checkin_post['post_type'] = 'checkin'; $checkin_post['post_status'] = 'publish'; $checkin_post['post_title'] = get_the_title($checkInId); $checkin_post['post_author'] = $user_ID; if ($user_ID) { // データベースに投稿を追加 $posted_ID = wp_insert_post( $checkin_post ); // 今投稿したチェックインデータのカスタムフィールド「checkin_spot_id(チェックインした城のID)」に値を追加 add_post_meta($posted_ID, 'checkin_spot_id', $checkInId); } }
  48. 保存結果
  49. 結果出力応用例
  50. WebAPIとの連携
  51. WebAPIとは? ざっくり言うと 他のウェブサービスが提供している データを自由に使える 使用例 天気情報 お城のある 地域の天気を 表示
  52. WebAPIとは? 各お城ページに該当する地域の 天気を毎日調べて手動で更新 しているわけではありません!
  53. 天気予報データが提供されている http://weather.livedoor.com/weather_hacks/webservice
  54. データの取得方法 指定のURLにアクセスすると データが取得出来ます。 http:// APIデータ提供元URL + パラメーター http://weather.livedoor.com/forecast/webservice/json/v1 ?city=400040 city が 400040(福岡県・久留米市)の情報
  55. パラメーターの確認 提供されているAPIごとに 用意されているパラメータは違う Livedoor天気情報の場合 「city」というパラメーターと、 その値が用意されている。 お城のページごとに地域に あった city の 値を登録
  56. 各お城詳細ページに天気の地域IDを登録 お城のページごとに、 そのお城のある地域に該当する city の 値を登録します。 ここではカスタムフィールド ‘weatherID’ を用意して、そこに手動で 登録します。
  57. 天気情報の結果をリクエストするURLを作成 $city = esc_html(post_custom('weatherID')); お城の詳細ページで、カスタムフィールドに 保存した地域の天気IDを取得する。 $url = "http://weather.livedoor.com/forecast/webservice/json/v1?city=".$city; リクエストするURLを作成
  58. リクエストした結果を受け取って配列に $json_tenki_data = file_get_contents($url); リクエストURLにアクセスすると、その地域の 天気情報データが得られます。 Livedoor 天気情報の場合データは json 形式なので、変 数名もわかりやすいように $json_ としています。 jsonのままだと使いにくいので配列に変換 $tenkis = json_decode($json_tenki_data);
  59. 取得した天気データの中身の確認 print '<pre>';print_r($tenkis);print '</pre>'; このへんが使えそう
  60. 取得した天気データの中身の確認 •日付のラベル •天気(文字) •天気の画像 を使いたい
  61. 必要な部分の取り出して出力 $tenkis_forecasts = $tenkis->forecasts; 今日明日の天気情報部分のみ格納 <?php foreach ($tenkis_forecasts as $key => $dayTenki) { ?> <dl> <dt class="today"><?php echo $dayTenki->dateLabel ?></dt> <dd class="data"> <img src="<?php echo $dayTenki->image->url ?>" alt" /><br /> <?php echo $dayTenki->telop ?> </dd> </dl> <?php } ?> ※実際にはエスケープ処理します。
  62. サンプルソース // お城の詳細ページで、カスタムフィールドに保存した地域の天気IDを取得する $city = esc_html(post_custom('weatherID')); // 地域のIDが入っていたら実行 if ($city): // リクエストするURLを作成 $url = "http://weather.livedoor.com/forecast/webservice/json/v1?city=".$city; // 指定のエリア(都市)の情報をjson形式で取得 $json_tenki_data = file_get_contents($url); // 配列に格納 $tenkis = json_decode($json_tenki_data); // 今日明日の天気のみ $tenkis に格納 $tenkis_forecasts = $tenkis->forecasts; ?> <?php foreach ($tenkis_forecasts as $key => $dayTenki) { ?> <dl> <dt class="today"><?php echo esc_html($dayTenki->dateLabel); ?></dt> <dd class="data"> <img src="<?php echo esc_html($dayTenki->image->url); ?>" alt="<?php echo esc_html($dayTenki->image->title); ?>" /><br /> <?php echo esc_html($dayTenki->telop) ; ?> </dd> </dl> <?php } ?> <?php endif; ?>
  63. 参考資料 http://www.communitycom.jp/2012/07/14/wordvolcano/ WordPressプラグイン & WebAPI 活用ガイドブック 星野邦敏、西川伸一 WordPressの機能を簡単に拡張できる「プラグイン」と、外部 のWebサービスの機能や情報をWordPressサイトで使うこと のできる「WebAPI」を、辞典形式に紹介している書籍です。 いろんなAPIが探せる http://wafl.net/
  64. WordPress + API で 面白いサービスを作りましょう!
  65. ご清聴ありがとうございました。
Advertisement