Forum

Building a store locator

Hi all,

Just wondering if anyone had any suggestions as to how I might go about building a store locator in Perch?

The current map field type only allows one marker to be added to a map, but I would need to be able to add many, preferably cluster them together when they're too many close together and customise the marker icon.

Would this be a case of creating a new field type based on the map field type and using the Google maps API to implement the clustering?

Are there any Perch devs out there who'd be willing to price and do this work for a project?

Thanks in advance, Adam

Adam Green

Adam Green 0 points

  • 7 years ago
Drew McLellan

Drew McLellan 2638 points
Perch Support

You could use the map type to gather the data for each store, and then do something custom on the front end to display a clustered map.

Check out https://grabaperch.com/developers if you're looking to hire in some help!

Hi Adam,

If you're still looking for someone, my dev partner and I have recently worked on a project for a large, well known, UK based DIY retailer, building the store locator for their new site. (Albeit not in Perch).

Happy to discuss requirements.

Thanks

Lee

Thanks for the suggestion Drew and for the offer Lee. It looks like the budget isn't there for the project I had in mind so unfortunately I have to put this one aside for the time being. I'll keep you in mind though Lee should the requirement arise again. Best, Adam

No worries, happy to help if I can.

Regards

Lee

Bit of a late reply on this but I've set-up a store/stockists locator here https://www.justequine.co.uk/stockists.php. It uses a Google maps script + Perch template and perch_content_custom to create the locations data file. So, the client enters stockists in Perch and they appear on map. Yay!

I've just done this too. The site is not launched yet, but when it is I will write it up in a blog post or something and add the link here.

But basically, I used: https://github.com/bjorn2404/jQuery-Store-Locator-Plugin to do the front-end,

used this as the template for the admin area:


<perch:content id="name" type="text" label="Dealer name" /> <perch:content id="map" type="map" label="Address" /> <perch:content id="address" /> etc etc etc

and used perch_content_custom as Clive suggested to create the store locations like this:

<?php
    header('Content-type: application/xml');
    include('perch/runtime.php');

    $stores = perch_content_custom('Stores', array(
        'skip-template'=>true,
        'raw'=>true
    ));

    $xml_out = '<?xml version="1.0" encoding="utf-8"?><markers>';

    foreach( $stores as $store ) {
        $xml_out .= '<marker name="'. $store['name'] .'" lat="' . $store['map']['lat'] .'" lng="' . $store['map']['lng'] .'" category="Store" address="'. $store['address'] .'" address2="'. $store['address2'] .'" city="'. $store['city'] .'" state="'. $store['county'] .'" postal="'. $store['postcode'] .'" country="'. $store['country'] .'" phone="'. $store['tel'] .'" email="'. $store['email'] .'" web="'. $store['website'] .'" />';
    }

    $xml_out .=  '</markers>';
    print_r($xml_out);
?>

Thanks, Paul.

Updated to change initial array to $stores instead of $dealers.

Yes, I used the same Google Maps script.

My locations.php perch_content_custom code is

<?php header('Content-type: application/xml');
        include('../perch/runtime.php'); ?><?php perch_content_custom('Stockists List', array(
                'filter'=>'show',
                'match'=>'eq',
                'value'=>'Yes'
            )); ?>

My Stockists List perch template contains a <perch:help> block and the appropriate xml declaration and <markers><marker> structure, like this

<perch:help>Help text for the client here</perch:help>
<perch:before><?xml version="1.0" encoding="utf-8"?><markers></perch:before>
<perch:if exists="stockistsname"><marker name="<perch:content id="stockistsname" type="text" label="Stockist Name" required="true" />" lat="<perch:content id="latitude" type="text" label="Latitude" help="For example, 51.225506" />" lng="<perch:content id="longitude" type="text" label="Longitude" help="Make sure you add minus sign if present, for example -0.005866" />" category="" address="<perch:content id="address1" type="text" label="Address 1"/>" address2="<perch:content id="address2" type="text" label="Address 2" />" city="<perch:content id="towncity" type="text" label="Town or City" />" state="<perch:content id="county" type="text" label="County" />" postal="<perch:content id="postcode" type="text" label="Post code" />" country="UK" phone="<perch:content id="telephone" type="text" label="Telephone" />" email="" web="<perch:content id="website" type="text" label="Website address" help="Enter the full URL including https://" />" hours1="" hours2="" hours3="" featured="" features=""/>
<perch:content type="checkbox" id="show" value="Yes" label="Show on site?" suppress="true" /></perch:if><perch:after></markers></perch:after>

I used a type=checkbox Perch field to allow the client to turn on/off the display of any stockist.

Good idea about the turning on and off of stockists. Hadn't thought about that but no doubt that will be handy.

The main difference that I see between our approaches is that I used to type="map" content type to allow the client to search for the address and do the geocoding that way instead of manually adding it. That's why I did raw=true so that I could get the lat/long out of the Perch map field-type. I couldn't see a way to get it through the normal methods.

Good idea re the map type. I didn't know or didn't look into getting the lat and long values from that. I used a geocode page for my client (there was an example in the maps script) but using Perch maps field is better and I'll likely use that if I have another example to do.

Cheers!

Simon Clay

Simon Clay 127 points

Sounds great, I look forward to seeing the blog post about it.

Looking forward to the blog post. I'm having difficulty in making the connection between the table in my perch database and the actual store locator.

Not really grasping how to generate the JSON file so that my store locator can use my data rather than the dummy locations.xml file.

So you've done the bit to allow the admin to enter the store locations in Perch?

If so, create a locations.php file with something like this in:

<?php
    header('Content-type: application/xml');
    include('perch/runtime.php');

    $dealers = perch_content_custom('Stores', array(
        'skip-template'=>true,
        'raw'=>true
    ));

    $xml_out = '<?xml version="1.0" encoding="utf-8"?><markers>';

    foreach( $stores as $store ) {
        $xml_out .= '<marker name="'. $store['name'] .'" lat="' . $store['map']['lat'] .'" lng="' . $store['map']['lng'] .'" category="Store" address="'. $store['address'] .'" address2="'. $store['address2'] .'" city="'. $store['city'] .'" state="'. $store['county'] .'" postal="'. $store['postcode'] .'" country="'. $store['country'] .'" phone="'. $store['tel'] .'" email="'. $store['email'] .'" web="'. $store['website'] .'" />';
    }

    $xml_out .=  '</markers>';
    print_r($xml_out);
?>

You will need to amend that based on your field names of course.

Then visit it in a browser and see if you get an XML file generated. As it has a .php file name Perch will process it and output an XML file to the browser for you. You should be able to amend this for JSON too, but I used XML.

Then in your JS, you need to tell the plug in that your filename has changed:

$(function() {
    $('#map-container').storeLocator({
        'dataLocation' : '/data/locations.php',
            // ... deleted other config for brevity
    });
  });

The plug in doesn't care that the suffix is .php as the server gives it XML back anyway, but before that Perch will update it for you.

Does any of that help?

Yeah kinda, I've got the locations.php file outputting as a blank XML, but in the process I have lost the editable region from within Perch (luckily with only 1 test entry in it). How do I make it come up in Perch as an editable region again?

Thanks Paul, your help is appreciated :).

This solutions works great, but a little gotcha if following Paul's example to the t is change $dealers to $store

cheers Paul and Clive

Oops. Thanks for pointing that out Dan. I've amended that post to correct it to $stores to hopefully avoid confusion.

And also oops. I said I was going to write a blog post about it. Shame on me...