Software Engineering in WordPress and Musings on the Deep Life

Refactoring Our Code For Google Maps in WordPress

Up to this point, a fair amount of work has been done in terms of introducing Google Maps in WordPress:

  • Twentyfifteen is setup to communicate with the Google Maps API
  • A map is being displayed in a custom template
  • There are two markers that are placed on the map
  • Each marker has its own InfoWindow used to display some information

There’s still more content that could be covered, and I’ll talk about some of the advanced content in another article but, for now, it’s time to refactor some of the code so that it’s more manageable, is organized in more of the “WordPress way,” and lays the foundation to more easily introduce new features.

Namely, all of the work that’s been done up to this point can be moved into a child theme and all of the code that’s been placed in the template can be abstracted out into its own files.

A Child Theme Google Maps in WordPress

I’m going to continue moving forward with working on a child theme for WordPress by introducing a child theme based off of Twentyfifteen.

Naturally, you can use whatever theme you’d like but for the purposes of this series, I’m going to continue with the theme that that’s been used throughout this series.

Create The Child Theme

This series of article assumes that you know the basics of creating a child theme. If not, the Codex has a good article on where to start.

From here, we’re going to create a directory in wp-content called twentyfifteen-maps and we’ll introduce a few files and subdirectories. Specifically, add the following files:

  • `functions.php`
  • `style.css`
  • `template-maps.php`

And then add the following subdirectories

  • `css`
  • `js`

Ultimately, the directory structure for the child theme should look something like this:

twentyfifteen-maps

Of course, this won’t actually work (let alone even show up in WordPress right now), but we’ve got the necessary files in place in order to create the child theme.

Define The Stylesheet

In order to make the theme accessible via the WordPress Dashboard, we need to add some information to style.css.

This will display the theme in the dashboard; however, there still won’t be a lot of functionality to the theme beyond what the base Twentyfifteen theme offers.

Next, the base theme styles need to be included in the child theme. To do this, adding the following function to the child theme’s functions.php file:

Now we can start actually moving the functionality that we’ve added to the base theme into the new theme.

The Google Maps API Library

Up until this point, the Google Maps API has been added using a normal script tag, but a better way to do it would be to use wp_enqueue_script so add this to functions.php:

Next, the code that’s been powering Google Maps can be added to its own file:

And then it can be included in functions.php:

If you’re new to child theming, notice the call to get_stylesheet_directory_uri(). This is being used in place of get_template_directory_uri() because we’re including files that are in the context of the child theme.

The rule of thumb is this:

If you’re working with files in a theme or in a base theme, use `get_template_directory_uri()`. If you’re working with files in a child theme, then use `get_stylesheet_directory_uri()`.

Anyway, notice that these two files pass true as to whether or not to load them in the footer of the page or not. This is because the library and the Google Maps code need to be loaded and fired after the page has loaded (this also improves page performance, but that’s a topic outside the scope of this article).

Add The Stylesheet

There’s a small bit of styling that exists in the template file from previous articles in this series that can be moved into its own file. In the css directory, create style.css and then add the following code to it:

Next, updating functions.php so that the add_twentyfifteen_maps_styles function includes the file as well:

This will ensure that the map looks the same in the child theme as it did in the parent theme.

Introduce The Template

Finally, add the template file to the child theme’s root directory. To do this, add template-maps.php – the file should be really simple and include nothing but the following:

Now the child theme can be activated, a page can be created, the template can be applied, and the Google Map will load.

Is That All?

In terms of the basics of using Google Maps within the context of WordPress, yes. This provides a way to keep all of the code abstracted into its own files, uses the proper WordPress APIs to include theme all, and also retains the same functionality that’s been used throughout this series.

There are plenty of advanced topics as it relates to Google Maps in terms of what can be achieved (such as calculating distances, getting directions, and so on) which may be interesting for a future set of article. If you’re interested, leave a comment; otherwise, that brings this [rather long] series to an end.

Series Posts

  1. Using The Google Maps API and WordPress
  2. Integrating Google Maps in WordPress
  3. Displaying Google Maps in WordPress
  4. Google Maps in WordPress: Adding a Marker
  5. InfoWindows for Google Maps in WordPress
  6. Refactoring Our Code For Google Maps in WordPress

17 Comments

  1. Anastasia

    Where are you including the script in the functions file? I only see the stylesheets.

    • Tom

      See the section “The Google Maps API Library” and let me know if that clears it up. If not, I can explain further :).

      • Elsie Gilmore

        I’m wondering if she’s asking where you are including public.js. I don’t see where you’re including that, and my map isn’t rendering. Any assistance would be appreciated! Thanks!

        • Tom

          Ah, good point! See the gist right under the line that reads:

          And then it can be included in functions.php:

          As it shows where it should be enqueued. If this doesn’t help, let me know!

  2. Andrew Herder

    Hey, thanks for taking the time to write this. It’s definitely helpful as I’m finding myself using the JS API more and more with each project. How do you tend to get all of the marker information and display it on the map generally?

    Lately I’ve been running the query on the wordpress backend when a user saves a relevant post and saving it as a super long JSON string with update_option(). (So that I don’t run the same exact query every time somebody sees the map.)

    But even then that still leaves me with echoing out this HUGE string (2000+ locations sometimes) onto like a data-attribute. Is there a better way to go about doing this? Having my SQL database and JS interact feels like I’m just doing janky things with PHP as my middleman.

    I guess what I’m asking is, in a situation where, lets say you have a custom post type “store” with location data on each post, how do you generally go about grabbing that information and displaying it?

    Cheers,

    Andrew

    • Tom

      How do you tend to get all of the marker information and display it on the map generally?

      Personally, this depends on how many markers that I need to display. If it’s a low number or something that’s not too taxing on the browser, then I’ll load them all up at once.

      If, on the other hand, then I’ll normally load what’s available for a given viewport size and cache it (like maybe in the transients table). That way, the data is available more quickly and can be grabbed via caching plugins.

      If things get really complicated, then I’ll use an async process either via Ajax or an entire cron job for grabbing location information on the server side, saving it, and then just rendering it using Ajax.

      So it really depends on the situation for me.

      Lately I’ve been running the query on the wordpress backend when a user saves a relevant post and saving it as a super long JSON string with update_option(). (So that I don’t run the same exact query every time somebody sees the map.)

      I get what you’re trying to do with the general post, but I’d refine it a bit.

      First, rather than having a super long JSON string, why not separate it into chunks via some type of metric? Perhaps by zip code or postal code, perhaps by just an arbitrary number, or based on some other relevant aspects of your code so you can pull information at a fine-tuned level rather than getting everything back at once?

      Secondly, I’d recommend storing the results in the options table and the transients table. Then, check to see if it’s in the transients table. If so, use that; otherwise, execute the query on demand, store it in the options table and in the transients table. This is basically what happens during cache invalidation. But only do this after you’ve improved performance with the options table.

      Finally, and I suppose this is my attempt to answer your final question:

      I guess what I’m asking is, in a situation where, lets say you have a custom post type “store” with location data on each post, how do you generally go about grabbing that information and displaying it?

      This would depending on a metric like postal code, area code, geographic boundaries, etc. (it really depends on the area that you’re that metric.

      I can’t give a definitive answer because I know this really matters on what you’re mapping. I can do things for the US that I can’t do for, say, Canada and vice versa. One other thing is that if you really want to control something like this, then you can also display viewport zooming, but that’s kind of a hack depending on what your needs are.

      I hop this helps or at least gives some ideas on how to approach this another way!

  3. Philip

    Awesome series. Really great!! I appreciate you taking the time to write this long and detailed explanation.

    I kept getting API key error and I can’t understand why I could not get it to work without adding my API key this way: http://stackoverflow.com/questions/16203618/google-maps-api-javascript-in-wordpress as per Josh’s answer.

    I am using this plugin as well https://wordpress.org/plugins/address-geocoder/ where I have added the API key. I was hoping that would have been enough but it was not.

    May I ask how you have added the API key?

    Thank you

    • Tom

      If you look at this gist, you’ll see where I have API_KEY. This is where your API key could go.

      Hope this helps!

  4. Robert Wilde

    Hey Tom, as always awesome work. really helped a lot

    I have a small issue that I was hoping you could assist with. I have everything enqueued and can see the section being added into the source but all I get on the frontend is a grey box.

    Any ideas on what may be causing the lack of map

    • Tom

      I have a small issue that I was hoping you could assist with. I have everything enqueued and can see the section being added into the source but all I get on the frontend is a grey box.

      This usually happens when there’s a problem with the JavaScript or something isn’t enqueued in the right order.

      Make sure that your scripts are in the right order, that there are no errors in the console, and that the scripts are in the footer. I’ve found that to be much more useful than trying to include them in the header.

      • Robert Wilde

        OK great thanks got that working OK. I have another question about displaying multiple markers.

        I am adding data to my public.js using wp_localize script and it works very well. I am getting the data for the locations from a plugin in the backend. All data great but I can get the markers to display in a for loop.

        I am outputting the data from the “marker = new google.maps.Marker” and the data is the same but in the loop I don’t get the marker on the page.

        Any ideas? How would you iterate an array of data to display several markers?

        Thanks again for an awesome series of posts.

        • Robert Wilde

          Sorry Tom, I seriously thought I was going mad but after putting on my glasses and taking a closer look, realised I had used the Lat variable in both the lat & lng position in the loop.

          Always the smallest thing that gets you.

          • Tom

            Always the smallest thing that gets you.

            Always.

  5. Grietje Goedkoop

    Hello Tom,

    Thanks for this extremely well explained tutorial about Google Maps.

    The only thing I want to know is when do you need to incorporate the Google API key? So far it all works fine without.

    Or have I overlooked a step somewhere?

    Best Regards, Grietje Goedkoop

    • Tom

      Great question! If you look at this code you’ll see where you’ll need to add it.

  6. Chloe

    Thanks so much for taking the time to write this series!

    It was exactly what I needed and I’ve managed to follow along and build a map within my WordPress theme with no prior knowledge of the Google Maps API.

    • Tom

      That’s fantastic! I love to hear that :).

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

© 2023 Tom McFarlin

Theme by Anders NorenUp ↑