a-blog cmsのカスタムフィールドとしてMapboxを使用する方法(IE11対応)
Mapboxとは
Mapboxは世界中で採用されている地図サービスです。近年、日本でも徐々に利用されるようになってきています。今回は、Mapboxをカスタムフィールドとして使用できるようにするまでの手順を紹介します。作業をすすめることで以下のような地図をa-blog cmsのカスタムフィールドとして作成できるようになります。本実装では、マップカテゴリーのエントリーを作成するときにのみMapboxカスタムフィールドが表示されるようになります。
事前準備
a-blog cmsのカスタムフィールドとしてMapboxを使用するためにMapbox側で準備するものが2つあります。
- 1. アクセストークン: MapboxのWebページ(https://www.mapbox.jp/)でアカウントの作成を行うことで簡単に入手できます。
- 2. スタイルURL:MapboxStudio(https://studio.mapbox.com/)というツールを使い、地図の見た目を決める「スタイル」を作成してください。スタイルの作成後にスタイルURLを入手することができます。
ブログのカスタムフィールドを作る
/themes/利用中のテーマ/admin/blog/field.html に以下のコードを追加します。
<h3 class="acms-admin-admin-title2">Mapboxアクセストークン登録</h3>
<table class="adminTable acms-admin-table-admin-edit">
<tr>
<th><label for="input-text-mapbox_accesstoken">アクセストークン</label><i data-acms-tooltip="アクセストークンを設定します。" class="acms-admin-icon-tooltip js-acms-tooltip-hover"></i></th>
<td>
<input type="text" name="mapbox_accesstoken" value="{mapbox_accesstoken}" id="input-text-mapbox_accesstoken" class="acms-admin-form-width-large" />
<input type="hidden" name="field[]" value="mapbox_accesstoken" />
</td>
</tr>
<tr>
<th><label for="input-text-mapbox_styleurl">スタイルURL</label><i data-acms-tooltip="スタイルURLを設定します。" class="acms-admin-icon-tooltip js-acms-tooltip-hover"></i></th>
<td>
<input type="text" name="mapbox_styleurl" value="{mapbox_styleurl}" id="input-text-mapbox_styleurl" class="acms-admin-form-width-large" />
<input type="hidden" name="field[]" value="mapbox_styleurl" />
</td>
</tr>
</table>これにより、管理ページ > ブログ > カスタム設定 にMapboxをa-blog cms内で利用する際に必要となるアクセストークンの入力欄、表示する地図のスタイルを決定するスタイルURLの入力欄が追加されます。
追加された入力欄に事前準備で入手したアクセストークンとスタイルURLを入力し、保存してください。
マップカテゴリー
本実装ではマップカテゴリーにおけるエントリー作成・変更画面においてのみMapboxのカスタムフィールドが表示されるようにします。管理画面>カテゴリー>新規カテゴリー作成にて、カテゴリー名を「マップ」、コードネームを「map」として作成ボタンを押してください。
Mapboxをカスタムフィールドとして使用するためのJSを追加
/themes/利用中のテーマ/js/ にmapboxfield.jsを作成し、
以下のリンクのコードを貼り付けてください。
管理側フォームの実装
/themes/利用中のテーマ/admin/entry/ccd/ に以下のコードを書いたmap.htmlを追加します。
<!-- Maboxライブラリ読み込み -->
<script src='https://api.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.js'></script>
<link href='https://api.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.css' rel='stylesheet' />
<!--Mapbox Geocoderの読み込み 検索フォームに入力した場所の位置を取得 -->
<script src="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-geocoder/v4.5.1/mapbox-gl-geocoder.min.js"></script>
<link rel="stylesheet"
href="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-geocoder/v4.5.1/mapbox-gl-geocoder.css"
type="text/css" />
<script src="/js/mapboxfield.js"></script>
<!-- Mapboxライブラリ読み込み ここまで-->
<!-- BEGIN_MODULE Blog_Field -->
<!-- 管理画面>ブログ>カスタム設定に入力した値の呼び出し -->
<div id="accesstoken_styleurl" data-accesstoken="{mapbox_accesstoken}" data-styleurl="{mapbox_styleurl}"></div>
<!-- END_MODULE Blog_Field -->
<!-- 地図が挿入される -->
<div id='fmapwrapper' style="width: 820px; height: 320px; max-width: 100% ; margin-left: auto; margin-right: auto;">
<div id='fmap' style='width: 820px; height: 80%; max-width: 100%;' data-lat="{fmapbox-lat}" data-lng="{fmapbox-lng}"
data-zoom="{fmapbox-zoom}" data-pitch="{fmapbox-pitch}" data-bearing="{fmapbox-bearing}"
data-mapsize="{fmapbox-mapsize}" data-maptype="field">
</div>
<!-- 地図の検索ボックス -->
<div id="geocoder" style="width: 100%; height: 45px;" class="geocoder"></div>
</div>
<!-- BEGIN_MODULE Touch_Edit -->
<table class="acms-admin-table-admin-edit">
<tr>
<th>経度</th>
<td>
<input id="lng" type="text" name="fmapbox-lng" value="{fmapbox-lng}" class="acms-admin-form-width-full" />
<input type="hidden" name="field[]" value="fmapbox-lng" />
</td>
</tr>
<tr>
<th>緯度</th>
<td>
<input id="lat" type="text" name="fmapbox-lat" value="{fmapbox-lat}" class="acms-admin-form-width-full" />
<input type="hidden" name="field[]" value="fmapbox-lat" />
</td>
</tr>
<tr>
<th>ズーム</th>
<td>
<input id="zoom" type="text" name="fmapbox-zoom" value="5" class="acms-admin-form-width-full" />
<input type="hidden" name="field[]" value="fmapbox-zoom" />
</td>
</tr>
<tr>
<th>角度</th>
<td>
<input id="pitch" type="text" name="fmapbox-pitch" value="{fmapbox-pitch}"
class="acms-admin-form-width-full" />
<input type="hidden" name="field[]" value="fmapbox-pitch" />
</td>
</tr>
<tr>
<th>回転</th>
<td>
<input id="bearing" type="text" name="fmapbox-bearing" value="{fmapbox-bearing}"
class="acms-admin-form-width-full" />
<input type="hidden" name="field[]" value="fmapbox-bearing" />
</td>
</tr>
</table>
<!-- END_MODULE Touch_Edit -->この時点でマップカテゴリーのエントリー作成・変更画面ではMapboxのカスタムフィールドが表示できるようになります。
エントリー詳細画面におけるMapboxカスタムフィールドの表示
_entry.htmlの追加
/themes/利用中のテーマ/map/ に以下のコードを書いた_entry.htmlを追加します。
<!DOCTYPE html>
<html class="no-js" lang="ja">
<head>
@include("/include/head/meta.html")
@include("/include/head/link.html")
@include("/include/head/js.html")
</head>
<body>
<!-- ヘッダー -->
@include("/include/header.html")
<!-- ページタイトル -->
@include("/include/header/page-title.html")
<!-- トピックパス -->
@include("/include/header/topicpath.html")
<div class="acms-container js-pretty-scroll-container">
<!-- ※管理用パーツ -->
@include("/admin/action.html")
<div class="acms-grid">
<main class="acms-col-lg-9 main">
<div class="main-inner is-space-right">
<!-- タグフィルター -->
@include("/include/tag/filter.html")
<!-- エントリーボディ(日付無し) -->
@include("/include/entry/body-no-date.html")
<!-- 確認用テンプレート -->
@include("/include/check-seo.html")
</div>
</main>
<div class="acms-col-lg-3 side">
<div class="js-pretty-scroll">
<!-- エントリーリスト -->
@include("/include/entry/list.html")
<!-- カテゴリーリスト -->
@include("/include/category/list.html")
<!-- 検索フォーム -->
@include("/include/parts/search.html")
<!-- ピックアップリスト -->
@include("/include/entry/summary-pickup.html")
<!-- バナー -->
@include("/include/siteparts/banner.html")
<!-- リンクリスト -->
@include("/include/siteparts/link-list.html")
<div class="acms-hide-pc">
<!-- モバイル:ナビゲーションメニュー -->
@include("/include/parts/mobile-nav.html")
<!-- SNSアカウントへのリンク -->
@include("/include/footer/sns-link.html")
</div>
</div>
</div>
</div>
</div>
<!-- お問い合わせ -->
@include("/include/footer/suggest.html")
<!-- フッター -->
@include("/include/footer.html")
</body>
</html>
body-no-date.htmlの追加
/themes/利用中のテーマ/include/entry/に以下のコードを書いた、body-no-date.htmlを追加します。
<!-- BEGIN_MODULE Entry_Body -->
<!-- BEGIN notFound -->
<section class="acms-entry">
<h2 class="not-found-title">Not Found</h2>
<p>ただいまページを準備しております。もうしばらくお待ちください。</p>
</section>
<!-- END notFound -->
<!-- 1記事▼▼ -->
<!-- BEGIN entry:loop -->
<div class="acms-box-medium">
@include("/admin/entry/revision-info.html")
</div>
<article class="entry clearfix {entry:loop.class}">
@include("/admin/entry/title.html")
<!-- エントリーのタイトル 開始▼▼ -->
<!-- BEGIN title:veil -->
<header class="acms-page-header page-header">
<!-- BEGIN_MODULE Touch_Entry --><h1 class="entry-title"><a href="{titleUrl}">{title}</a></h1><!-- END_MODULE Touch_Entry --><!-- BEGIN_MODULE Touch_NotEntry --><h2 class="entry-title"><a href="{titleUrl}">{title}[raw]</a></h2><!-- END_MODULE Touch_NotEntry -->
</header>
<!-- END title:veil -->
<!-- BEGIN entry-column:veil -->
<div class="acms-entry entry-column">
<div class="acms-grid entry-column-grid">
<!-- カスタムフィールドの読み込み -->
@include("/include/entry/field.html")
<!-- BEGIN unit:veil -->
@include("/include/unit.html")
<hr class="clearHidden" />
<!-- END unit:veil -->
<!-- 続きを読む -->
@include("/include/parts/continue.html")
<!-- BEGIN_MODULE Touch_Entry -->
<!-- カスタムフィールドの読み込み -->
@include("/include/entry/field_foot.html")
<!-- END_MODULE Touch_Entry -->
</div>
</div>
<!-- END entry-column:veil -->
<!-- BEGIN formBody -->
@include("/include/form/unit.html")
<hr class="clearHidden" />
<!-- END formBody -->
@include("/admin/entry/edit-%{IS_ADMIN}.html")
<!-- BEGIN_MODULE Touch_Entry -->
<footer class="entry-footer">
<div class="clearfix">
<div class="entry-tag-wrapper acms-col-md-6">
<!-- BEGIN tag:veil -->
<dl class="entry-tag">
<dt class="acms-inline-space entry-tag-icon"><span class="acms-icon-tag"></span><span class="acms-hide-visually">タグ</span></dt>
<!-- BEGIN tag:loop -->
<dd class="entry-tag-item"><a href="{url}">{name}</a></dd>
<!-- END tag:loop -->
</dl><!-- END tag:veil -->
</div>
<div class="acms-col-md-6">
<!-- SNSシェアボタン -->
@include("/include/parts/sns-customize.html")
</div>
</div>
</footer>
<!-- END_MODULE Touch_Entry -->
<div class="acms-box-medium">
@include("/admin/entry/action.html")
</div>
</article>
<!-- END entry:loop -->
<!-- 1記事▲▲ -->
<!-- ページャー -->
@include("/include/parts/pager.html")
<!-- END_MODULE Entry_Body -->
field.htmlの追加
/themes/利用中のテーマ/include/entry/に 以下のコードを書いた、field.htmlを追加します。
@include("/include/field/entry/ccd/%{CCD}.html")
@include("/include/field/entry/ecd/%{ECD}")
/themes/利用中のテーマ/include/field/entry/ccd/ に以下のコードを書いたmap.htmlを追加します。
<!-- Maboxライブラリ読み込み -->
<script src='https://api.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.js'></script>
<link href='https://api.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.css' rel='stylesheet' />
<script type="text/javascript" src="js/mapboxfield.js"></script>
<!-- BEGIN_MODULE Blog_Field -->
<!-- 地図作成のためのアクセストークンとスタイルURL -->
<div id="accesstoken_styleurl" data-accesstoken="{mapbox_accesstoken}" data-styleurl="{mapbox_styleurl}"></div>
<!-- END_MODULE Blog_Field -->
<div id='fmapwrapper' style="width: 820px; height: 320px; max-width: 100% ;">
<div id='fmap' style='width: 100%; height: 100%; max-width: 100%;' data-lat="{fmapbox-lat}" data-lng="{fmapbox-lng}"
data-zoom="{fmapbox-zoom}" data-pitch="{fmapbox-pitch}" data-bearing="{fmapbox-bearing}"
data-styleurl="{fmapbox_styleurl}" data-comment='{fmapbox-comment}' data-mapsize="{fmapbox-mapsize}"
data-maptype="show">
</div>
</div>これで、カスタムフィールドで設定したMapboxの地図がエントリー詳細画面で表示されるようになります。
Mapboxを安全に使用する方法
本実装ではMapboxのアクセストークンが開発者ツールを通じて見られるようになっています。本番環境での使用の際には以下のリンクの内容に従い、URL制限の有効化を行ってください。URL制限を追加したトークンは指定URLから発信されたリクエストのみ処理をするため、Webアプリのアクセス・トークンをよりセキュアにする事が可能です。
https://docs.mapbox.com/jp/help/troubleshooting/how-to-use-mapbox-securely/