Cwicly containers break shortcode from 3rd party pluging

Description:
This issue is possibly related to this one.

I’m encountering an issue when trying to display a block via shortcode generated by WP Maps Pro. I’ve been struggling to find a solution to add Google maps to my site via ACF for over a month now. Nothing has worked so far.

WP Maps Pro seems to work, but I am getting an error in the console on the frontend. Testing in a number of different environments, revealed that when wrapped in any Cwicly container, the shortcode breaks.

I used a barebones Gutenberg installation as a control, and it worked as expected there. Once I installed Cwicly and wrapped the shortcode with a DIV, it breaks.

Here’s a video (it’s 10min, sorry), where I explain and demonstrate the problem.
https://jam.dev/c/7135d1ba-52fd-416c-8d8e-f9ac31e7bcc8

  • WordPress version: 6.1.1
  • Cwicly Plugin version: 1.2.9.2.3

I can share access to the InstaWP test site for you to review.

As a follow-up. I’ve still been trying to find workarounds and doing troubleshooting on my own.

To be clear, the issue I outlined above remains.

However, my immediate need to display a dynamic Google Map has been addressed by consulting ACF’s documentation and using the code provided on this page: ACF | Google Map

I previously tried and was unsuccessful. What I now realize is that Google Maps requires jQuery to be loaded on the page the map is being called.

By adding a code snippet that enqueues jQuery for this post type my map works just fine.

I imagine that Cwicly (very wisely) disables jQuery by default. Is there a way to get it to run conditionally, otherwise? It’s possible I might have missed something else.

Apologies, as this is outside my realm of knowledge, generally.

Hi @owynter,

Just about to do this for a site and as you have already done it want to check with you.

Did you find a different solution in the end or was this best option?

This was how I did it.

You can see the implementation here: Chalet Genesis - Island Dream Properties

Scroll down the page.

I can share the code snippets if you’d like.

If you have time, that will be much appreciated, thank you.

It will be great to start with a known to be working solution we can quickly customise.

Here you go:

1. First, you need to enqueue Google Maps in your installation. Add your Google Maps API key in line 1 :

<script defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY_HERE"></script>
<script type="text/javascript">
(function( $ ) {

/**
 * initMap
 *
 * Renders a Google Map onto the selected jQuery element
 *
 * @date    22/10/19
 * @since   5.8.6
 *
 * @param   jQuery $el The jQuery element.
 * @return  object The map instance.
 */
function initMap( $el ) {

    // Find marker elements within map.
    var $markers = $el.find('.marker');

    // Create gerenic map.
    var mapArgs = {
        zoom        : $el.data('zoom') || 16,
        mapTypeId   : google.maps.MapTypeId.ROADMAP
    };
    var map = new google.maps.Map( $el[0], mapArgs );

    // Add markers.
    map.markers = [];
    $markers.each(function(){
        initMarker( $(this), map );
    });

    // Center map based on markers.
    centerMap( map );

    // Return map instance.
    return map;
}

/**
 * initMarker
 *
 * Creates a marker for the given jQuery element and map.
 *
 * @date    22/10/19
 * @since   5.8.6
 *
 * @param   jQuery $el The jQuery element.
 * @param   object The map instance.
 * @return  object The marker instance.
 */
function initMarker( $marker, map ) {

    // Get position from marker.
    var lat = $marker.data('lat');
    var lng = $marker.data('lng');
    var latLng = {
        lat: parseFloat( lat ),
        lng: parseFloat( lng )
    };

    // Create marker instance.
    var marker = new google.maps.Marker({
        position : latLng,
        map: map
    });

    // Append to reference for later use.
    map.markers.push( marker );

    // If marker contains HTML, add it to an infoWindow.
    if( $marker.html() ){

        // Create info window.
        var infowindow = new google.maps.InfoWindow({
            content: $marker.html()
        });

        // Show info window when marker is clicked.
        google.maps.event.addListener(marker, 'click', function() {
            infowindow.open( map, marker );
        });
    }
}

/**
 * centerMap
 *
 * Centers the map showing all markers in view.
 *
 * @date    22/10/19
 * @since   5.8.6
 *
 * @param   object The map instance.
 * @return  void
 */
function centerMap( map ) {

    // Create map boundaries from all map markers.
    var bounds = new google.maps.LatLngBounds();
    map.markers.forEach(function( marker ){
        bounds.extend({
            lat: marker.position.lat(),
            lng: marker.position.lng()
        });
    });

    // Case: Single marker.
    if( map.markers.length == 1 ){
        map.setCenter( bounds.getCenter() );

    // Case: Multiple markers.
    } else{
        map.fitBounds( bounds );
    }
}

// Render maps on page load.
$(document).ready(function(){
    $('.acf-map').each(function(){
        var map = initMap( $(this) );
    });
});

})(jQuery);
</script>

This is standard code. We added a custom icon to our map. If you want, I can share that as well.

2. Next, you need load your Google API key in ACF.

<?php

function my_acf_init() {
    acf_update_setting('google_api_key', 'YOUR_API_KEY_HERE');
}
add_action('acf/init', 'my_acf_init');

3. Finally, you can then add a map to your template. For this you will need a Cwicly Code block you can place wherever. Take note of where you need to add your ACF map field.

<?php 
// Enqueue JQuery on the page to load Google Maps
function my_script() {
        wp_enqueue_script( 'jquery' );
    }
add_action( 'wp_enqueue_scripts', 'my_script' );

// Get Coordinates from ACF Field
$location = get_field('your_acf_map_field_here');
if( $location ): ?>
    <div class="acf-map" data-zoom="16">
        <div class="marker" data-lat="<?php echo esc_attr($location['lat']); ?>" data-lng="<?php echo esc_attr($location['lng']); ?>"></div>
    </div>
<?php endif; 
?>

You’ll still need a bit of CSS to style the box as you see fit, as well as make it responsive.

This is ours, but yours, of course, will be different. Just be mindful of whatever class names you use in this CSS and the previous PHP script.:

.acf-map {
    width: 100%;
    height: 400px;
    border: var(--cc-color-10) solid 1px;
}

.acf-map img {
   max-width: inherit !important;
}```

And that should do it. 

Let me know if you need further guidance.

Thanks, much appreciated.

That all seems straightforward enough. We will be implementing this over the next few days.

If it is as simple as adding the icon property to the Marker, then we should be good to go.

Yup, you got it. I just removed the bit of code since it was pointing to a directory/file you obviously wouldn’t have.

Let me know how it works out.