Radial Search & Results Page – WordPress Tutorial

Performing a radial search (showing results based on location, zip code, etc) in WordPress is one of the hardest things I’ve had to figure out how to do. It held me back in many projects and was always a source of frustration.

After trying many different plugins and tutorials, I have finally come up with a working solution. Today I’m going to share that with you.

 

This solution includes many different components. They are as follows:

1. A PHP function to calculate the distance between two zip codes.

2. A javascript function to generate the link to our results page with given parameters.

3. The HTML form to search by our parameters.

4. Getting parameters from the URL

5. A WordPress loop to run the distance calculation on our posts.

6. Another WordPress loop to actually display our results.

 

As you can see it’s pretty complicated, but I’m going to break it down for you. You may notice I’m using functions like get_field or the_field in some of the PHP. Those are shortcut functions to get custom meta data from our posts and are generated from the brilliant Advanced Custom Fields plugin. You do not need to use this plugin, just be aware that you will need to alter your code to get the meta values in your situation. So let’s get to the code.

 

Calculating the distance between two zip codes.

Fortunately for us, Google provides a free API for looking up a ZIP code and providing the GPS coordinates. Originally I had believed that you could simply calculate the location of a ZIP code based on its value but that, as it turns out, is not how it works.

Fortunately there is a premade chunk of code that ties into Google’s API and returns those values for us. I was unable to find the original source, but there are a bunch of random sites sharing the same code. Here it is:

As you can see, the first function, getLnt, finds the latitude and longitude of the zip code. The second function, getDistance, then calculates the distance between that and a second zip code. We will use this later to calculate the distance between two dynamic points.

 

Generating the parameter-filled link to our results page

Let’s set up the javascript function to generate a link to our results page. This function does a couple things. First, it gets the values from our form that we are setting up later and adds them to an array. This array is then appended to the target url and will later tell our function what values to use.

To customize this for your own use, replace the IDs with your own element’s HTML IDs. For example, your input ID for the postal code input may not be “postal_code”, so you would need to change that.

The URL at the end will need to be your results page. For me, I actually want the search page and the results page to be one and the same. All of the code I am sharing here resides on a page template, which I have selected for use on this page. It might not be the best practice, but for illustration purposes it’s the easiest to work with that way.

The “SearchDistance” variable is one that I have set up to change the distance the user wishes to search. For example, if you only want to display results from within 50 miles, you enter it in SearchDistance.

 

Displaying the HTML search form

This part is pretty straight-forward. You just want to make sure that your input IDs are correct and matched up to the javascript function from earlier. I put everything in a table to keep it neat. I also added the values to these, which will get the value from the URL and repopulate the inputs with the proper value, if you have already performed a search. This is great for usability so that users don’t have to re-enter information if they wish to alter their search.

 

Getting parameters from the URL

Now we need to pass the parameters from the URL into our query so that we can find the correct results. Here’s what I have for the two parameters I am using:

This section will get the parameters we passed into the URL and turn them into PHP variable for later use. It first checks to make sure they are set in the URL, and THEN sets them to a parameter.

 

Calculating the distance from each of our posts

Now comes the fun part, and the part it took me ages to figure out. I even sought help at Stack Overflow, but nobody seemed to know how to begin the process of running a calculation on every post before displaying them.

The simple solution, I realized, was to run two loops. The first would go through each potential result, run the calculation on it, and then add it to an array of posts to be queried again if it passed the calculation. So for this first loop, we can add whatever we want to a standard $args array to do a preliminary filter on our posts. In my case, I’m just going to filter by page template and another meta key value unrelated to this tutorial. You can modify yours to filter for anything you like.

Then, in the loop itself, we just run our distance calculation and add passing post IDs to our $results string, which we will use later in our second loop.

Now we have an array of post IDs that we can use to query in our second loop, which will actually display our results. This should be friendly with pagination as well, and since it won’t be querying any superfluous posts, won’t add too much load time either.

 

Displaying the final results on the page

Now we just run our final loop to display the results. The $args are going to be pretty straightforward. You can use the parameter post__in to search for posts with the IDs that we have stored up in our $results array. Here is the code for the whole thing. Keep in mind, you can adjust the section that actually displays the results however you want. This is just how I did it!

And that should be it! There’s a lot to it but it’s not so hard if you break it down. The nice thing about this method is that you can fairly adapt it to lots of other uses and custom queries. In a site I just built, I also have more complicated things like select boxes where the options auto-populate based on existing, in-use values. Let me know if this works for you, or if you have any questions!

About Brian Johnson

Brian Johnson is a website developer and designer living in Minneapolis, Minnesota with a passion for code and WordPress. He spends his days building WordPress websites for small businesses, developing new code with the online community, and living life.

11 Comments on “Radial Search & Results Page – WordPress Tutorial”

    1. At the moment, no. I’ve used it on a number of client sites successfully, but I don’t have permission to share them here. That could also be a security issue if someone were to find a vulnerability in this code.

  1. Could you explain how I might show results that fall between a certain distance range? See between 25 and 50 miles away…

  2. Hi, Brian. Thanks for sharing this, it has been very helpful. Just wondering how to go about sorting the results from nearest first? Would love some tips. Thanks.

  3. Excellent post. Thank you for this, I was racking my brain to try and work out the logic/components I needed to go through to get something similar working for a real estate site – also a fan of ACF

  4. Very interesting solution. I have something in common. Don’t know yet how to solve it. I am using Beaver Builder pagebuilder and use Beaver Themer to build custom archive templates in combinations with the use of a CPT and CF’s (made in ACF). I do use Search&Filter Pro to filter on two fields I created: height and width (the site is about calculating glass windows). The filter works fine on the existing fields height and width to determine which window types fall in that range. However their is also the surface of the window. Within ACF in the backend I made a field and in that field I made the little PHP calculation and store the value in that field.

    Howver I don’t wnat to have the people searching in the front-end to fille in the surface theirself based on the given height and width. So in the search a kind of a hidden value (or field) should do the clacultion for the surface and then filter the results. Any idea how I can do that?

  5. Hi Brian,

    I’m building a new website for multiple vendors to sell their goods locally. Should this become bigger than the twin cities, I would like customers to be able to search for products within a certain proximity/radius to their home since they’ll be picking up the items. Similar to groupon.com

    I see you have thoughts on a radial search on WordPress…. I’m wondering if this would work with the Flatsome theme http://preview.themeforest.net/item/flatsome-multipurpose-responsive-woocommerce-theme/full_screen_preview/5484319 (I’m using Vendor Shop)

    Your help is appreciated!!

    Anna

    1. It’s good to see other people from the Twin Cities!

      For this type of integration, I would recommend going with something already-built for WooCommerce such as the WooCommerce Geolocation plugin here: http://woogeolocation.com/woocommerce-geolocation/

      It should have the functionality you need, and you’ll just need to tweak it. I assume you’re using WooCommerce since you’re using Flatsome which is a theme I’ve actually worked with before. The theme shouldn’t really matter, but you might as well use something that integrates fully and easily with WooCommerce.! Good luck!

      1. Hi brian, I purchased and set up the woocommerce geolocation plugin but it did not work for me at all. What’s worse, the seller has the worst customer service ever. I have contacted them about the problem I am having with their plugin but they have yet to respond. it’s so irritating.

Leave a Reply

Your email address will not be published. Required fields are marked *