🆕 Bricks 2.4 已发布:查询循环性能提升 40%,迁移教程同步更新 →

首页 / 中文教程 / 教程

用 ACF 从 CPT 动态填充 Bricks 地图标记(PART 1)

教程:在 Bricks 中用 Leaflet 与 ACF 从自定义文章类型动态生成地图标记,含完整 PHP 与 JS 代码,可直接复用。

Ray ChanRay Chan·2026-08-18·约 3 分钟
目录
  1. 1.前置要求
  2. 2.为自定义文章添加字段
  3. 3.填充门店数据
  4. 4.JavaScript 初始化
  5. 5.入队脚本
  6. 6.Bricks 设置
  7. 7.小结

用 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 &copy; <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: '&copy; <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 管理专属代码片段。

Ray Chan

站长

Ray Chan

WordPress Developer & Bricks Specialist

WordPress developer with 10+ years of client builds. Switched to Bricks in 2023 — now builds fast WordPress sites and migrates legacy Elementor/Divi projects.

延伸阅读