用 ACF 从 CPT 动态填充 Bricks 地图标记(PART 1)
本教程提供可粘贴的 PHP 与 JS 代码,用来在 Bricks 编辑器中创建一个动态地图,其标记(markers)来自一个自定义文章类型(Custom Post Type)。本篇是该地图系列的 PART 1,后续可参考 按分类术语过滤的 PART 4。
前置要求
- Bricks Builder(任意版本)
- 已启用 Bricks 子主题
- 一个自定义文章类型(本例中使用
stores) - 已安装 ACF 免费版或 PRO 版
为自定义文章添加字段
在我们的示例中,我们将创建一组门店(stores),并想在交互式地图上展示它们。为此,我们需要给每个门店添加经纬度。我们用 ACF 来完成这件事:
填充门店数据
现在进入我们的 stores 自定义文章,添加门店列表:
为每家门店填好数据:
JavaScript 初始化
在本教程中,我们将使用 Leaflet.js——一个开源、对移动端友好的交互式地图 JavaScript 库。
首先,从作者官网下载文件,把 leaflet.js 和 leaflet.css 两个文件都上传到你的子主题目录中。
我们再创建一个 init.js 文件来设置所有地图选项。在本例中,我们创建了一个名为 leaflet_init.js 的文件,并粘贴了以下代码:
window.addEventListener('load', () => {
const canvas = document.querySelector('#map');
if (!document.body.classList.contains('bricks-is-frontend') || canvas === null ){
return;
}
var mbAttr = 'Map data © <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>';
var mbUrl = 'https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1Ij...B5aw';
var streets = L.tileLayer(mbUrl, {id: 'mapbox/streets-v11', tileSize: 512, zoomOffset: -1, attribution: mbAttr});
var osm = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
});
var satellite = L.tileLayer(mbUrl, {id: 'mapbox/satellite-v9', tileSize: 512, zoomOffset: -1, attribution: mbAttr});
var map = L.map('map', {
center: [canvas.dataset.leafletLat, canvas.dataset.leafletLong],
zoom: canvas.dataset.leafletZoom,
layers: [osm, cities]
});
var baseLayers = {
'OpenStreetMap': osm,
'Streets': streets,
'Satellite': satellite
};
var layerControl = L.control.layers(baseLayers).addTo(map);
});
入队脚本
现在,我们用基于 ACF 自定义字段的条件方式把文件入队。打开你的 functions.php 文件并粘贴以下代码:
add_action( 'wp_enqueue_scripts', function ()
{
// Enqueue your files on the canvas & frontend, not the builder panel. Otherwise custom CSS might affect builder)
if ( !bricks_is_builder_main() && class_exists( 'ACF' ) )
{
// Leaflet
if ( get_field( 'activate_leaflet' ) )
{
wp_enqueue_script( 'leaflet', get_stylesheet_directory_uri() . '/js/leaflet/leaflet.js', array() , '1.8.0' );
wp_enqueue_style( 'leaflet', get_stylesheet_directory_uri() . '/css/leaflet/leaflet.css', '1.8.0' );
wp_enqueue_script( 'leaflet_init', get_stylesheet_directory_uri() . '/js/leaflet_init.js', array( 'leaflet' ) , filemtime( get_stylesheet_directory() . '/js/leaflet_init.js' ) );
$cities = "var cities = L.layerGroup();";
// CUSTOM QUERY
$args = array(
'post_type' => 'stores',
'posts_per_page' => '-1',
'post_status' => 'publish'
);
$query = new WP_Query($args);
// GET POST SETTINGS
if ( $query->have_posts() ):
while ( $query->have_posts() ):
$query->the_post();
// Variables
$id = get_the_ID();
$title = get_field( 'store_name' );
$address = get_field( 'store_address' );
$lat = get_field( 'store_lattitude' );
$long = get_field( 'store_longitude' );
// Add each store
$cities .= "var store" . $id . " = L.marker([" . esc_attr( $lat ) . "," . esc_attr( $long ) . "]) . bindPopup(`<a href=" . get_permalink() . "><h4>" . esc_attr( $title ) . "</h4></a><br>" . $address . "`).addTo(cities);";
endwhile;
endif;
wp_reset_postdata();
wp_add_inline_script( 'leaflet_init', $cities, 'before' );
}
}
});
如上方代码所示,我们创建了一个 WP Query 函数来循环遍历所有门店,取出全部数据(如门店名称、地址、纬度、经度),并放进一个 JavaScript 变量中,供 Leaflet 用来在地图上生成标记/弹窗。
在这个具体例子中,我们会循环遍历 stores 自定义文章中所有已发布的文章。如果你需要进一步筛选数据(例如按分类法、作者或 meta_key),可以随意修改 WP Query 的 $args 参数来满足需求。
Bricks 设置
现在把地图插入到编辑器中。为此,我们需要创建一个 div 并把它的 ID 改为 map:
然后需要指定宽度和高度:
最后,创建一些 data 属性来正确定位地图:
data-leaflet-zoom是地图加载时的默认缩放级别。在本例中设为6。data-leaflet-lat是地图加载时的默认纬度。在本例中设为37.4532775。data-leaflet-long是地图加载时的默认经度。在本例中设为-81.2703729。
小结
通过「ACF 给门店录入经纬度 + WP Query 把数据注入到内联 JS 变量 + Leaflet 初始化渲染」,即可在 Bricks 中用子主题和原生 div 实现由自定义文章类型驱动的动态地图标记。配合条件入队(仅在前端且开启 activate_leaflet 时加载),既保证性能又不影响编辑器。关于把代码以片段方式管理,也可参考 在 Bricks 中使用 WPCodeBox 管理专属代码片段。
延伸阅读
Bricks 用 ACF Checkbox 字段渲染自定义 SVG 图标列表
教程:Bricks 用 ACF Checkbox 字段渲染自定义 SVG 图标列表——acf 附完整代码可直接复用,适合外贸独立站与 WordPress 开发者。
tutorialBricks 按 ACF Gallery 图片数量做动态条件输出
教程:Bricks 按 ACF Gallery 图片数量做动态条件输出——acf 附完整代码可直接复用,适合外贸独立站与 WordPress 开发者。
tutorialBricks 查询循环输出 ACF 图片字段的 Alt、Caption、标题数据
教程:Bricks 查询循环输出 ACF 图片字段的 Alt、Caption、标题数据——acf 附完整代码可直接复用,适合外贸独立站与 WordPress 开发者。
tutorialBricks 中输出 ACF Relationship 关联文章的数量
教程:Bricks 中输出 ACF Relationship 关联文章的数量——acf 附完整代码可直接复用,适合外贸独立站与 WordPress 开发者。
