lordsimal / bolt-geolocation-field
📝 Bolt 扩展,用于添加地理位置字段类型
Requires
- php: >=7.2.9
Requires (Dev)
- bolt/core: ^4.0 || ^5.0
- symplify/easy-coding-standard: ^7.0
README
本扩展是为 BoltCMS 4 编写的
此扩展允许你在 ContentTypes 中使用 type: geolocation
字段,如 contenttypes.yaml
中定义的那样
composer require lordsimal/bolt-geolocation-field
之后你将看到一个名为 config/extensions/bolt-geolocation.yaml
的新文件。
在这里,你必须插入你的 Google Maps JS API 密钥,否则字段将无法正确工作!
# Settings for Bolt Geolocation Field
default:
apikey: "<my-api-key>"
有关 Google Maps JS API 密钥的更多信息,请参阅下文。
之后,你可以创建一个具有字段类型 geolocation
的新字段
test:
name: Test
singular_name: Test
fields:
location:
type: geolocation
viewless: false
taxonomy: [ ]
locales: ['en', 'nl', 'pt_BR', 'es']
singleton: true
icon_many: "fa:home"
icon_one: "fa:home"
字段可以包含 autocompleteOptions 键,以设置 componentRestrictions,例如
location:
type: geolocation
autocompleteOptions:
componentRestrictions:
country: 'us'
要查看所有可用选项,请参阅谷歌文档
有了这个,你可以在后端看到该字段
你可以通过选择 搜索
并输入你想要的地方来搜索地点
或者,如果你有位置的纬度和经度,你可以通过 纬度 & 经度
区域输入它们。
如 GIF 所示,在输入手动纬度和经度时,需要点击 更新 Google 地图
按钮。
你还可以设置你想要的缩放级别
Google 地图 API 密钥
如果你还没有 API 密钥,请访问 https://console.developers.google.com/ 并创建一个新的项目。
之后,你必须为此项目启用以下 API
- 地图 JavaScript API
- 这是通过 JS 创建 Google 地图所必需的
- 地点 API
- 这是在搜索地点时拥有良好搜索行为所必需的
之后,你需要通过 凭据 菜单创建一个 API 密钥。
我建议你至少通过 HTTP 引用 限制此密钥,以便只有你的网站可以使用该 API 密钥。
现在生成的 API 密钥需要插入到你的 config/extensions/bolt-geolocation.yaml
文件中。
最后,你需要在 https://console.cloud.google.com/billing 下创建一个 计费账户 并将其链接到之前创建的 API 控制台项目
https://cloud.google.com/billing/docs/how-to/modify-project#confirm_billing_is_enabled_on_a_project
Google 要求你插入一个,否则它将无法按预期工作。
有关更多信息,请参阅https://developers.google.com/maps/documentation/javascript/usage-and-billing
为什么我选择 Google 地图 JS API 而不是内嵌版本?
请相信我,我已经尝试在不使用 API 密钥的情况下实现它。
但遗憾的是,Google 只允许每个页面加载 1 个 iFrame。 https://stackoverflow.com/questions/15388897/google-maps-inside-iframe-not-loading
因此,你不能有多个定义为 type: geolocation
的字段,因为只有第一个有效,其他都不会。
因为据我所知,目前没有地图服务提供商允许在不使用API密钥的情况下嵌入多个地图,所以我选择了最受欢迎的一个。
在前端访问值
基本上,所有字段中的内容都保存在一个JSON中。
BoltCMS将JSON作为字符串返回,因此我们首先需要对其进行解码。
{% set field_value = record.location %}
{% if field_value is not json %}
The given field value for <code>{{ record.location.name }}</code> is not a valid json
{% else %}
{% set location_json = record.location|json_decode() %}
<div>Selected: {{ location_json.selected }}</div>
<div>Zoom: {{ location_json.zoom }}</div>
<div>Search: {{ location_json.search }}</div>
<div>Latitude: {{ location_json.lat }}</div>
<div>Longitude: {{ location_json.long }}</div>
{% endif %}
-
Record此处是当前内容类型的条目。
-
location是你在contenttypes.yaml文件中给字段起的名字
-
location_json.selected是search或latlong之一
-
location_json.zoom的值在0到19之间
-
location_json.search是搜索词,即搜索的位置
-
location_json.lat是纬度值
-
location_json.long是经度值
通过iframe输出简单的嵌入地图
如果你不想自己使用Google Map JS API输出地图,你可以使用上面的数据通过iframe
输出嵌入地图
{% set field_value = record.location %}
{% if field_value is not json %}
The given field value for <code>{{ record.location.name }}</code> is not a valid json
{% else %}
{% set location_json = record.location|json_decode() %}
{% if location_json.selected == "search" %}
{% set gmap_query = location_json.search|url_encode %}
{% elseif location_json.selected == "latlong" %}
{% set gmap_query = location_json.lat ~ ',' ~ location_json.long %}
{% endif %}
<div class="geolocation-field-iframe-wrapper">
<iframe class="geolocation-field-iframe"
src="https://maps.google.com/maps?q={{ gmap_query }}&t=&z={{ location_json.zoom }}&ie=UTF8&iwloc=&output=embed"
frameborder="0" scrolling="no" marginheight="0" marginwidth="0">
</iframe>
</div>
{% endif %}
我建议你也在你的应用中设置以下CSS
.geolocation-field-iframe { height: 500px; /* or what height you need */ width: 100%; } .geolocation-field-iframe { height: 100%; width: 100%; }
警告:Google只允许每个URL使用1个iframe。参见https://stackoverflow.com/questions/15388897/google-maps-inside-iframe-not-loading
因此,如果你需要在同一页面上输出多个地图,你需要在你的前端实现Google Maps JS API。
运行PHPStan和Easy Codings Standard
首先,确保已安装依赖项
COMPOSER_MEMORY_LIMIT=-1 composer update
然后运行ECS
vendor/bin/ecs check src