Movable TypeでGoogleMAP座標のコンテンツタイプ追加してみた。

らら
らら
Movable TypeでGoogleMAP座標のコンテンツタイプ追加してみた。

はじめに

コンテンツタイプにGoogleMAPの座標設定あると便利かとおもって・・・

チャレンジしてみた・・

コードはっく。

ヒントは、コンテンツデータに日付と時間が2つのエリアあるのでこちらを参考にしようかと・・・

lib\MT\ContentFieldTypeにそれぽい・・感じが・・

DateTime.pmとCommon.pmが関係ありそう・・

field_html_params、data_load_handlerとかぐらいでいけそう??

lib\MT\ContentFieldType.pmでレジストリの登録は参考にできそう

データベースは、mt_content_typeでblob形式だったので・・・参考にできなかった・・

コンテンツデータはmt_cd、こっちもblob・・・

最終のディレクトリ構造


ContentMapCoordtField
│  config.yaml
├─lib
│  │  ContentMapCoordtField.pm
│  └─ContentMapCoordtField
│	  │  App.pm
│	  └─ContentFieldType
│			  ContentMapCoordtField.pm
│			  
└─tmpl
	│  config.tmpl
	│  selectmap.tmpl
	├─content_field_type_options
	│	  googlemap_coordinate.tmpl
	└─field_html
			field_html_googlemap_coordinate.tmpl

config.yaml

ContentFieldType.pmからレジストリの値とか参考にyaml形式に置き換えて・・


id: ContentMapCoordtField
name: ContentMapCoordtField
version: 1.0
author_name: 
author_link: 
description: <__trans phrase="This plugin adds a GoogleMap coordinate content field type.">
l10n_lexicon:
	ja:
		This plugin adds a GoogleMap coordinate content field type.: "GoogleMap座標コンテンツフィールドを追加"
		GoogleMap Coordinate: GoogleMap座標
		Google Maps API key: Google Maps API key
		Google Maps API ID: Google Maps ID
		Google Maps latitude : 緯度(lat)
		Google Maps longitude : 経度(lng)
		Google Maps Default Latitude : 地図中心緯度(lat)
		Google Maps Default Longitude : 地図中心 経度(lng)
applications:
	cms:
		methods:
			google_map_popup: ContentMapCoordtField::App::google_map_popup
tags:
	function:
		GoogleMapKey:	   $ContentMapCoordtField::ContentMapCoordtField::_hdlr_googlemap_key
		GoogleMapId:		$ContentMapCoordtField::ContentMapCoordtField::_hdlr_googlemap_id
		GoogleMapLatitude:  $ContentMapCoordtField::ContentMapCoordtField::_hdlr_googlemap_latitude
		GoogleMapLongitude: $ContentMapCoordtField::ContentMapCoordtField::_hdlr_googlemap_longitude
content_field_types:
	googlemap_coordinate:
		label: GoogleMap Coordinate
		data_type: 'text'
		order: 300,
		icon_class: 'ic_singleline'
		can_data_label_field: 0
		data_load_handler: $ContentMapCoordtField::ContentMapCoordtField::ContentFieldType::ContentMapCoordtField::data_load_handler
		field_value_handler: $ContentMapCoordtField::ContentMapCoordtField::ContentFieldType::ContentMapCoordtField::field_value_handler
		field_html: 'field_html/field_html_googlemap_coordinate.tmpl'
		field_html_params: $ContentMapCoordtField::ContentMapCoordtField::ContentFieldType::ContentMapCoordtField::field_html_params
		list_props:
			googlemap_coordinate:
				base: '__virtual.string'
				col: 'value_varchar'
				terms: $Core::MT::ContentFieldType::Common::terms_text
		options_html: 'content_field_type_options/googlemap_coordinate.tmpl'
		options:
			- label
			- description
			- required
			- display
			- initial_value
settings:
	googlemaps_api_key:
		default:
	googlemaps_id:
		default:
	googlemaps_def_latitude:
		default:
	googlemaps_def_longitude:
		default:
system_config_template: config.tmpl

lib\ContentMapCoordtField.pm

ここでは、プラグインの設定の値をMTタグとしてどこでも使えるように・・タグをつくる


package ContentMapCoordtField;
use strict;
use utf8;
use warnings;
my $PluginKey = 'ContentMapCoordtField';
sub instance {
	my ($app) = @_;
	$app ||= 'MT';
	$app->component($PluginKey);
}
#<$MTGoogleMapKey$>
sub _hdlr_googlemap_key {
	my $plugin  = instance();
	return $plugin->get_config_value('googlemaps_api_key');
}
#<$MTGoogleMapID$>
sub _hdlr_googlemap_id {
	my $plugin  = instance();
	return $plugin->get_config_value('googlemaps_id');
}
#<$MTGoogleMapLatitude$>
sub _hdlr_googlemap_latitude {
	my $plugin  = instance();
	return $plugin->get_config_value('googlemaps_def_latitude');
}
#<$MTGoogleMapLongitude$>
sub _hdlr_googlemap_longitude {
	my $plugin  = instance();
	return $plugin->get_config_value('googlemaps_def_longitude');
}
1;

lib\ContentMapCoordtField\App.pm

ここでは、GoogleMap座標選択ようのPOPUPだすテンプレート・・

一応MT経由で表示するように・・


package ContentMapCoordtField::App;
use strict;
use File::Basename;
my $PluginKey = 'ContentMapCoordtField';
sub instance {
	my ($app) = @_;
	$app ||= 'MT';
	$app->component($PluginKey);
}
sub google_map_popup {
	my $app = shift;
	my $param = {};
	my $q	= $app->param;
	my $lat	= $q->param('lat');
	my $lng	= $q->param('lng');
	my $lat_id	= $q->param('lat_id');
	my $lng_id	= $q->param('lng_id');
	my $plugin  = instance();
	my $googlemaps_api_key			= $plugin->get_config_value('googlemaps_api_key');
	my $googlemaps_def_latitude		= $plugin->get_config_value('googlemaps_def_latitude');
	my $googlemaps_def_longitude	= $plugin->get_config_value('googlemaps_def_longitude');
	my $website_terms = undef;
	if (my $blog_id = $app->param('blog_id')) {
		$website_terms = { 'id' => $blog_id };
	}
	$param->{lat}						= $lat;
	$param->{lng}						= $lng;
	$param->{lat_id}					= $lat_id;
	$param->{lng_id}					= $lng_id;
	$param->{googlemaps_api_key}		= $googlemaps_api_key;
	$param->{googlemaps_def_latitude}	= $googlemaps_def_latitude;
	$param->{googlemaps_def_longitude}	= $googlemaps_def_longitude;
	my $plugin = MT->component('ContentMapCoordtField');
	$plugin->load_tmpl('selectmap.tmpl', $param);
}
1;

lib\ContentMapCoordtField\ContentFieldType\ContentMapCoordtField.pm

ここではコンテンツタイプの定義、必須とか・・設定

あとContentFieldValueでの加工、保存のデータ構築?


package ContentMapCoordtField::ContentFieldType::ContentMapCoordtField;
use strict;
use warnings;
sub field_html_params {
	my ( $app, $field_data ) = @_;
	my ( $lat, $lng );
	my $value = $field_data->{value} || '';
	# for initial_value.
	$value = '' unless defined $value;
	$lat = '';
	$lng = '';
	if ( defined $value && $value ne '' ) {
		( $lat, $lng )	= split ', ', $value;
	}
	my $required = $field_data->{options}{required} ? 'required' : '';
	{	googlemap_coordinate_data => $value,
		 lat => $lat,
		 lng => $lng,
		 required => $required,
	};
}
sub data_load_handler {
	my ( $app, $field_data ) = @_;
	my $id   = $field_data->{id};
	my ( $lat, $lng );
	$lat = $app->param( 'lat-' . $id );
	$lng = $app->param( 'lng-' . $id );
	my $coordinate = $lat .", ". $lng;
	return $coordinate;
}
sub field_value_handler {
	my ( $ctx, $args, $cond, $field_data, $value ) = @_;
	my $coordinate = lc $args->{coordinate} || 'lng';
	my ( $lat, $lng );
	return if ( $coordinate ne 'lat' and $coordinate ne 'lng' );
	( $lat, $lng )	= split ', ', $value;
	if($coordinate eq 'lat') {
		return $lat;
	}elsif ($coordinate eq 'lng') {
		return $lng;
	} else {
		return $value;
	}
}
1;

tmpl\config.tmpl

プラグインの設定でつかうHTMLコード


<mtapp:setting
  id="contentmapcoordtfield-template_type"
  label="<__trans phrase="GoogleMap Coordinate">">
  <label for="contentmapcoordtfield-googlemaps_api_key"><__trans phrase="Google Maps API key"></label>
  <input type="text" name="googlemaps_api_key" id="contentmapcoordtfield-googlemaps_api_key" class="form-control w-100" value="<mt:var name="googlemaps_api_key" escape="html">">
  <label for="contentmapcoordtfield-def_latitude"><__trans phrase="Google Maps ID"></label>
  <input type="text" name="googlemaps_id" id="contentmapcoordtfield-googlemaps_id" class="form-control w-100" value="<mt:var name="googlemaps_id" escape="html">">
  <label for="contentmapcoordtfield-def_latitude"><__trans phrase="Google Maps Default Latitude"></label>
  <input type="text" name="googlemaps_def_latitude" id="contentmapcoordtfield-googlemaps_def_latitude" class="form-control w-100" value="<mt:var name="googlemaps_def_latitude" escape="html">">
  <label for="contentmapcoordtfield-def_longitude"><__trans phrase="Google Maps Default Longitude"></label>
  <input type="text" name="googlemaps_def_longitude" id="contentmapcoordtfield-googlemaps_def_longitude" class="form-control w-100" value="<mt:var name="googlemaps_def_longitude" escape="html">">
</mtapp:setting>

tmpl\selectmap.tmpl

GoogleMAPを使って、座標を取得できるようにしたHTML

これはどこからか、拝借したもの・・拝借先・・覚えてません。。すみません・・

マーカーの画像を使わないタイプがよかったので・・mt-staticとか個別になると面倒になるので・・


<!DOCTYPE html>
<html lang="ja" itemscope itemtype="http://schema.org/WebPage">
<head>
<meta charset="UTF-8">
<title>経度・緯度</title>
<script type="text/javascript" src="//maps.google.com/maps/api/js?sensor=true&key=<mt:var name="googlemaps_api_key">"></script>
<script type="text/javascript">
function value_set(lat,lng){
	if(!lat && !lng) {
		return [<mt:var name="googlemaps_def_latitude">,<mt:var name="googlemaps_def_longitude">];
	}
	return [lat,lng]
}
	var Lat_id			= "<mt:var name="lat_id">";
	var Lng_id			= "<mt:var name="lng_id">";
	var Lat				= "<mt:var name="lat">";
	var Lng				= "<mt:var name="lng">";
	var latlon;
	latlon = value_set(Lat,Lng);
	// 初期設定項目
	var initLat			= latlon[0];
	var initLng			= latlon[1];		// 初期表示する経度
	var crossSize		= 19;				// クロスの長さ
	var zoomLevelMin	= 0;				// ズームレベルの最大値
	var zoomLevelMax	= 21;				// ズームレベルの最小値
	var	zoomLevelInit	= 18;				// ズームレベルの初期表示値
	var mapOptions = {						// mapオプション
		zoom: zoomLevelInit,
		center: new google.maps.LatLng(initLat,initLng),
		navigationControl: true,
		scaleControl: true,
		mapTypeId: google.maps.MapTypeId.ROADMAP
	};
	var map;								// gmapオブジェクト
	var controlCross;						// センターに表示するクロス
	var lat		= 0;						// 緯度保持
	var lng		= 0;						// 経度保持
	var geocoder;							// ジオコーダー
	function createGmap()
	{
		geocoder = new google.maps.Geocoder();
		map = new google.maps.Map(document.getElementById("gmap"),mapOptions);
		// 中心マーカーの表示
		createCenterMaker();
		// イベントリスナーの登録
		google.maps.event.addListener(map,'center_changed',OnMapDraged);			// ドラッグ終了
		OnMapDrag();
	}
	function CrossControl(controlDiv, map)
	{
		var mapDiv = map.getDiv();
		var x = (mapDiv.offsetWidth  - crossSize + 1) / 2;
		var y = (mapDiv.offsetHeight - crossSize + 1) / 2;
		var controlCrossV = document.createElement('DIV');
		controlCrossV.style.position = 'absolute'
		controlCrossV.style.borderStyle = 'none none none solid';
		controlCrossV.style.borderWidth = '1px';
		controlCrossV.style.borderColor = 'red';
		controlCrossV.style.height = crossSize + 'px';
		controlCrossV.style.left = 0+ "px";
		controlCrossV.style.top = y+ "px";
		controlDiv.appendChild(controlCrossV);
		var controlCrossH = document.createElement('DIV');
		controlCrossH.style.position	= 'absolute'
		controlCrossH.style.borderStyle = 'solid none none none';
		controlCrossH.style.borderWidth = '1px';
		controlCrossH.style.borderColor = 'red';
		controlCrossH.style.width		= crossSize + 'px';
		controlCrossH.style.left		= (crossSize / 2) * -1+ "px";
		controlCrossH.style.top = mapDiv.offsetHeight / 2+ "px"; 
		controlDiv.appendChild(controlCrossH);
	}
	function createCenterMaker() {
		var CrossControlDiv = document.createElement('DIV');
		var crossControl	= new CrossControl(CrossControlDiv,map);
		CrossControlDiv.index = 1;
		map.controls[google.maps.ControlPosition.TOP].push(CrossControlDiv);
	}
	function moveMap()
	{
		lng = parseFloat(document.points.lng.value);
		lat = parseFloat(document.points.lat.value);
		map.panTo(new google.maps.LatLng(lat,lng));
	}
	function OnMapDrag()
	{
		latlng = map.getCenter();
		document.points.lng.value = latlng.lng();
		document.points.lat.value = latlng.lat();
	}
	function OnMapDraged()
	{
		OnMapDrag();
	}
function popup_end(lng,lat)
{
	opener.document.getElementById(Lat_id).value = lat;
	opener.document.getElementById(Lng_id).value = lng;
	window.close();
}
</script>
</head>
<body onload="createGmap()">
<div id="gmap" style="width: 500px; height: 400px"></div>
<br />
<form name="points"  method="post" action="">
	<input type="text" id="lat" name="lat" size="31" maxlength="20">
	<input type="text" id="lng" name="lng" size="32" maxlength="20">
	<br />
	<input type="hidden" name="url" value="">
	<input type="hidden" name="lat_tky" value="">
	<input type="hidden" name="lon_tky" value="">
	<input type="button" value="決定" onclick="popup_end(this.form.lng.value,this.form.lat.value)">
	</font>
</form>
</body>
</html>

tmpl\content_field_type_options\googlemap_coordinate.tmpl

これは、コンテンツデータの方で、表示するHTML


<mt:app:ContentFieldOptionGroup
   type="googlemap_coordinate">
  <mtapp:ContentFieldOption
     id="googlemap-coordinate-initial-lat"
     label="<__trans phrase="Google Maps latitude">">
    <input ref="initial_lat" type="text" name="initial_lat" id="googlemap-coordinate-initial-lat" class="form-control date-field w-25" value={ options.initial_lat } placeholder="">
  </mtapp:ContentFieldOption>
  <mtapp:ContentFieldOption
     id="googlemap-coordinate-initial-lng"
     label="<__trans phrase=" oogle Maps longitude">">
    <input ref="initial_lng" type="text" name="initial_lng" id="dgooglemap-coordinate-initial-lng" class="form-control time-field w-25" value={ options.initial_lng } placeholder="">
  </mtapp:ContentFieldOption>
</mt:app:ContentFieldOptionGroup>

tmpl\field_html\field_html_googlemap_coordinate.tmpl

ここでは、MAP選択POPUPに値を渡す部分を仕込んでおく、また、修正時、MAP選択した場合、その座標で地図を表示するようにごにょごにょしておく。

一応id名を渡しておくので、複数あった場合も対応できるかと・・・


<div class="row form-inline googlemap-coordinate-field-container group-container">
	<div class="col d-none d-md-block mb-0">
		<span>
			<input type="text" name="lat-<mt:var name="content_field_id" escape="html">" id="lat-<mt:var name="content_field_id" escape="html">" class="lat-field form-control text group html5-form content-field" value="<mt:var name="lat" escape="html">" placeholder="" mt:watch-change="1" mt:raw-name="1" <mt:var name="required">>
		</span>
		<span class="separator"> <__trans phrase=", "></span>
		<span>
			<input type="text" name="lng-<mt:var name="content_field_id" escape="html">" id="lng-<mt:var name="content_field_id" escape="html">" class="lng-field form-control text group html5-form content-field" value="<mt:var name="lng" escape="html">" placeholder="" mt:watch-change="1" mt:raw-name="1" <mt:var name="required">>
		</span>
		<div class="mt-3">
			<a id="mappopup_<mt:var name="content_field_id" escape="html">">
			<svg role="img" class="mt-icon--primary mt-icon--sm first-child last-child"><title class="first-child">Add</title><use xlink:href="/test_mt/mt/mt-static/images/sprite.svg#ic_add" class="last-child"></use></svg>
			座標選択
			</a>
		</div>
	</div>
</div>
<mt:setvarblock name="jq_js_include" append="1">
	$(document).on("click", "[id^=mappopup_]", function(){
		var id_str = $(this).attr("id");
		stArray = id_str.split("_");
		var id_lat = "lat-"+stArray[1];
		var id_lng = "lng-"+stArray[1];
		var lat = $('#'+id_lat).val();
		var lng = $('#'+id_lng).val();
		var url ='<mt:var name="script_url">?__mode=google_map_popup&lat_id=' + id_lat + '&lng_id=' + id_lng + '&lat=' + lat + '&lng=' + lng;
		win = window.open(url,"map_win","toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=no,width=600,height=600");
	});
</mt:setvarblock>

完成のイメージ

プラグイン

GoogleMAP座標のコンテンツタイプ

プラグインの設定

GoogleMAP座標のコンテンツタイプ

コンテンツタイプのイメージ

GoogleMAP座標のコンテンツタイプ

コンテンツデータの入力方法

GoogleMAP座標のコンテンツタイプ

ContentMapCoordtFieldでできたMTタグ

プラグインの設定で設定した値を取得できます。

MTGoogleMapLatitude、MTGoogleMapLongitudeは地図の中心座標です。地図選択POPUP等でも使用しています、


<$MTGoogleMapId$>
<$MTGoogleMapKey$>
<$MTGoogleMapLatitude$>
<$MTGoogleMapLongitude$>

ContentFieldValue

おいらが解析不十分で・・・内部的な保存が"緯度, 経度"で保存しています。CSVなどでエクスポートした場合、35.16991042521872, 136.90756276140058で1つで入ります。

なので、分割するためにContentFieldValueに要素を追加しています。

coordinate要素 指定なしは、35.16991042521872, 136.90756276140058で出力されます。

lat指定で35.16991042521872

lng指定で136.90756276140058


<mt:ContentFieldValue coordinate="lat">		緯度
<mt:ContentFieldValue coordinate="lng">		経度

作成したプラグインの使用例

Googlemap複数マーカー

google.maps.Markerがサポートなくなるそうなので、 google.maps.marker.AdvancedMarkerViewを使っています。


<script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
<script src="https://maps.googleapis.com/maps/api/js?key=<$MTGoogleMapKey$>&callback=initMap&libraries=marker&v=beta" defer></script>
<script>
var markers  = [
<mt:Contents content_type="アクセスマップ">
['<p><mt:ContentField content_field="店舗名"><mt:ContentFieldValue></mt:ContentField></p>','<mt:ContentField content_field="GoogleMAP座標"><mt:ContentFieldValue coordinate="lat"></mt:ContentField>','<mt:ContentField content_field="GoogleMAP座標"><mt:ContentFieldValue coordinate="lng"></mt:ContentField>'],
</mt:Contents>
];
function initMap() {
	var myOptions = {
		zoom: 12,
		center: new google.maps.LatLng(<$MTGoogleMapLatitude$>,<$MTGoogleMapLongitude$>),
		mapTypeId: google.maps.MapTypeId.ROADMAP,
		streetViewControl:false,
		mapId: 'DEMO_MAP_ID',		// 本番は<$MTGoogleMapId$>
	};
	var map = new google.maps.Map(document.getElementById("map"), myOptions);
	var infoWindow = new google.maps.InfoWindow();
	markers.forEach( function(value, i) {
		var gtitle	= markers[i][0];
		var glat	= parseFloat(markers[i][1]);
		var glng	= parseFloat(markers[i][2]);
		var Img = document.createElement("img");
		Img.src = "./marker1.png";
		Img.width	= 40;	// 横サイズ(px)
		Img.height	= 40;	// 縦サイズ(px)
		var marker = new google.maps.marker.AdvancedMarkerView({
			position : {
				'lat': glat,
				'lng': glng
			},
			map,
			title: gtitle,
			content: Img
		});
		marker.addListener("click", ({ domEvent, latLng }) => {
			const { target } = domEvent;
			infoWindow.close();
			infoWindow.setContent(marker.title);
			infoWindow.open(marker.map, marker);
		});
	});
}
window.initMap = initMap;
</script>
<style>
#map {
	height: 600px;
}
</style>
</head>
<body>
<div id="map"></div>
</body>
</code></pre>

上記ソースの結果はこんな感じ・・

GoogleMAP座標のコンテンツタイプ

制限事項

デフォルト値設定 デバックしてません・・・

入力値のチェック入っていません・・・

必須はどちらか1個かもしれません・・・

システムの検索・置換ロジックは、省いてます・・解析不足・・・

さいごに

GoogleMapは有償になったので、それでも問題ないって場合ですね・・

あたらしいのは・・mapIdとかの指定、div id="map"にサイズ指定しておかないとでなかったりと。。。不便・・・

製品版に標準につけてほしい。w

あ、あと。。サポートしていませんから。。うごかんぞぉーとか、クレーム入れないで・・w

あと、過去やったGoogleMapのコードが動かなくて・・?そっちに時間が・・かかったよぉ・・関連からどうぞ。。

では・・

追記

このプラグインは、検証の結果 Movable Type 9では動作しませんでした。

Movable Type 8.4.0 より、管理画面の JavaScript ライブラリを Riot.js から Svelte切り替わったことにより、Svelte対応が必要になるようです。

また、mt-config.cgiに UseRiot 1を追加することで、動作は確認しましたが、恒久的な対応かどうかはわかりません。

たぶん、config.yamlにoptions_script:を追加すればよさそうですが・・Svelteの学習コストが高さそうなので・・筆者には・・・

Movable Type 9では、管理画面のデザイン変わってたので、どうかとおもったのですが・・やはりって感じですね。おいらはこれを機に、プラグインつくるのやめます

追記2

こんなサイトあったので・・やってみた!

Svelte 環境で変わったコンテンツフィールドの追加方法について
https://github.com/movabletype/Documentation/wiki/Svelte-%E7%92%B0%E5%A2%83%E3%81%A7%E5%A4%89%E3%82%8F%E3%81%A3%E3%81%9F%E3%82%B3%E3%83%B3%E3%83%86%E3%83%B3%E3%83%84%E3%83%95%E3%82%A3%E3%83%BC%E3%83%AB%E3%83%89%E3%81%AE%E8%BF%BD%E5%8A%A0%E6%96%B9%E6%B3%95%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6

ディレクトリ構成はこれ


│  package-lock.json
│  package.json
│  rollup.config.ts
│  tsconfig.json
└─src
    │  googlemap_coordinate.ts
    │
    └─elements
            GoogleMapCoordinate.svelte
            type.ts

googlemap_coordinate.ts


import GoogleMapCoordinate from "./elements/GoogleMapCoordinate.svelte";
import { GoogleMapCoordinateOptions } from "./elements/type";
import type { CustomContentFieldMountFunction } from "@sixapart/mt-toolkit/contenttype";
const mountGoogleMapCoordinateSvelte: CustomContentFieldMountFunction = function (
  props,
  target
) {
  const emailSvelte = new GoogleMapCoordinate({
    props: props,
    target: target,
  });
  return {
    component: emailSvelte,
    destroy: () => {
      emailSvelte.$destroy();
    },
  };
};
export { GoogleMapCoordinate, mountGoogleMapCoordinateSvelte };

GoogleMapCoordinate.svelte

window.tranってやってるけど。yamlの日本語じゃないみたい・・だれか教えて・・

ここで、ContentFieldOptionを書く・・


<script lang="ts">
  import { Writable } from "svelte/store";
  import {
    ContentFieldOption,
    ContentFieldOptionGroup,
  } from "@sixapart/mt-toolkit/contenttype";
  import type {
    ConfigSettings,
    Field,
    OptionsHtmlParams,
  } from "@sixapart/mt-toolkit/contenttype";
  import type { GoogleMapCoordinateOptions } from "./type";
  // svelte-ignore unused-export-let
  export let config: ConfigSettings;
  export let fieldIndex: number;
  export let fieldsStore: Writable<Array<Field<GoogleMapCoordinateOptions>>>;
  // svelte-ignore unused-export-let
  export let optionsHtmlParams: OptionsHtmlParams;
  const id = `field-options-${$fieldsStore[fieldIndex].id}`;
  $fieldsStore[fieldIndex].options.initial_lat ??= "";
  $fieldsStore[fieldIndex].options.initial_lng ??= "";
</script>
<ContentFieldOptionGroup
  type="googlmap_coordinate"
  bind:field={$fieldsStore[fieldIndex]}
  {id}
  bind:options={$fieldsStore[fieldIndex].options}
>
  <ContentFieldOption id="googlmap-coordinate-initial-lat" label={window.trans("Google Maps latitude")}>
    <input
      {...{ ref: "initial_lat" }}
      type="text"
      name="initial_lat"
      id="googlmap-coordinate-initial-lat"
      class="form-control w-25"
      bind:value={$fieldsStore[fieldIndex].options.initial_lat}
    />
  </ContentFieldOption>
  <ContentFieldOption id="googlmap-coordinate-initial-lng" label={window.trans("Google Maps longitude")}>
    <input
      {...{ ref: "initial_lng" }}
      type="text"
      name="initial_lng"
      id="googlmap-coordinate-initial-lng"
      class="form-control w-25"
      bind:value={$fieldsStore[fieldIndex].options.initial_lng}
    />
  </ContentFieldOption>
</ContentFieldOptionGroup>

type.ts


export type GoogleMapCoordinateOptions = {
  initial_lat?: string;
  initial_lng?: string;
};

package-lock.json,package.json,rollup.config.ts,tsconfig.jsonは上記サイトから、上記ファイル名の記載の部分とプロジェクト名を変更して

下記実行で・・


npm install
npm run build-svelte

config.yamlでoptions_scriptを追加


        options_html: 'content_field_type_options/googlemap_coordinate.tmpl'
        options_script: 'options_script/googlemap_coordinate.tmpl'

googlemap_coordinate.tmpl

ここでの注意が・・・googlemap-coordinateがアンダーバーで無いことがネックです。

筆者は、ずっと、ここをgooglemap_coordinateで定義していて、コンテンツタイプで選択しても入力でねぇーー

コンパイルがわるいのか。。nextでやってみたり。。viteでやったりと・・・rollup、svelteでやるんだってとこと・・・


<script type="module">
  import {
    GoogleMapCoordinate,
    mountGoogleMapCoordinateSvelte,
  } from "<mt:var name='static_uri'>plugins/ContentMapCoordtField/dist/googlemap_coordinate.js?v=<mt:var name='mt_version_id' escape='url'>";
  ContentTypeEditor.registerCustomType(
    "googlemap-coordinate",
    mountGoogleMapCoordinateSvelte
  );
</script>

ContentFieldOptionタグ書くだけで。これは面倒。。特にJSのチェックだったりがないと・・面倒・・

最近、この手のフレームワークごとに。書き方違って・・めんどうね・・= > {} [] 記号がぁ・・・・

関連

GoogleMapが動かない・・?
https://www.omakase.net/blog/2024/06/googlemap-1.html

関連記事