Dynamically create a map marker for every post location, set in ACF

Hi there -

I have a CPT, “Events”. Each Event has an ACF field, “Location” which is a Google Maps field. This field returns details about that location, like address, latitude and longitude. Is it possible to use the Map element, where there is a marker for every Event? I’m familiar with ACF Loopers, but I can’t seem to get this to work without repeating the map element for each Event. Where I’m at now:

  • Parent element is a div with Looper Provider set to Query Builder > Event
  • Under this is the Map element with Looper Provider set to Dynamic Content > “{{dc:acf:post_field field="location"}}”. (Turning on Looper Consumer here causes the map to duplicate for every Event published.)
  • Under this is the Map Marker with Looper Consumer turned on. I tried grabbing latitude with {{dc:looper:field key="lat"}} with no luck. It does work when Looper Consumer is turned on for the Map element, but as mentioned in the bullet point above, doing this causes the map to duplicate.

Hello @webdesignteam,

Thanks for writing in! Normally, you element structure could be like this:

DIV - Looper Provider Query Builder / Looper Consumer
    Map - Looper Provider Dynamic Content
       Marker - Looper Consumer 

We would love to check your Map element settings if you would not mind provide us your WP details. You can create a secure note in your next reply with the following info:
– Link to your site
– WP login URL
– WP username
– WP password
– WP Administrator Role
– Confirmation that we can access and make changes to your site

To know how to create a secure note, please check this out: How The Forum Works

image

Best Regards.

Thanks for the reply! I’ve set it up the way you’ve described I believe, but the map element gets duplicated for every post published.

Unfortunately what you are doing isn’t going to work since you have to double loop, thus creating an additional map element. It’s a similar issue as what has come up before, but are ultimate solution is a “Fragment” element that is capable of only outputting the child elements. Letting you double loop and keep the same element structure of a map marker as the final looped item.

The only workarounds I could give you is to create a custom looper. Or to create a Twig template. Both would need to do the get_posts query and grabs each ACF location into a singular array. We would be happy to set this up for you through One. Let me know if you have any other questions.

Thanks @charlie, I was able to get it to work as you’ve described using a custom looper (code below if you’d like to proofread). The limitation I’m seeing now is although I can grab the key/value pairs for all the Event locations, I still need details from each Event to populate each map marker. For example, in addition to a Google Map location, each event also has a registration link. Is it possible to somehow grab that ACF field and load it into the map marker content?

// Custom Looper `events`
// Add a filter which Cornerstone can use
// We then reference this just as `events` in the Custom Looper UI
// =============================================================================
add_filter("cs_looper_custom_events", function() {

  // get all events
  $all_events = get_posts(array(
    'fields'         => 'ids',
    'posts_per_page' => -1,
    'post_type'      => 'events',
    'post_status'    => 'publish'
  ));

  // get all locations
  $out = [];
  foreach ( $all_events as $key => $post_id ) {
    $location = get_field('location', $post_id);
    $out[] = (array)$location;
  }

  // return data to loop through
  return $out;  
});

I’m not entirely sure what data you are trying to also grab, but you could add this data to the $location variable as an idea. To speed this up, you probably want to remove the fields argument in the get_posts function if you need data from the post in the location data.

    $post = get_post($post_id);
    $location = (array) get_field('location', $post_id);
    $location['description'] = $post->post_description;
    // $location['post'] = $post; // You could also just pass in the entire post.
    $out[] = $location;

This got me where I needed to be, thanks for your detailed help! I hope this is helpful to others with a similar task.

1 Like

Hi @webdesignteam,

Glad that we are able to help you.

Thanks

As a followup to this, I was actually able to make this work in a standard looper using type=“object” formatting.

I was able to set up a looper using the normal query builder on the map element, pulling in the “events” CPT. I then added a marker element as a consumer, with {{dc:acf:post_field field="location" type="object" key="lat"/key="lng"}} in the latitude/longitude fields, and things like {{dc:post:title}}, {{dc:acf:post_field field="example_text"}}, and {{dc:acf:post_field field="example_photo" type="object" key="url"}} in the content field.

I suspect that @charlie’s suggestion of pulling the entire post through the custom looper would get me where I needed to be as well, but this was easier for me to use things from both loop levels this way.

1 Like

Thanks for the follow up, Andy.

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.