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'
要查看所有可用选项,请参阅Google 文档
有了这个,您可以在后端看到该字段
您可以通过选择 搜索
然后键入您想要的位置来搜索地点
或者,如果您有位置的经纬度,您可以通过 经纬度
区域输入它们。
如 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 %}
-
记录这里是指当前的内容类型条目。
-
位置是在contenttypes.yaml文件中您为字段指定的名称
-
location_json.selected可以是搜索或latlong
-
location_json.zoom的值介于0到19之间
-
location_json.search是搜索词,即搜索的位置
-
location_json.lat是纬度值
-
location_json.long是经度值
输出一个简单的嵌入式地图
如果您不想使用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中有一个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