Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

General Questions

General questions about getting started with SilverStripe that don't fit in any of the categories above.

Moderators: martimiz, Sean, biapar, Willr, Ingo, swaiba, simon_w

Zip Code Store Locator or Google Map Store Locator

Go to End

16 Posts   6984 Views


28 September 2009 at 5:05pm (Last edited: 28 September 2009 5:09pm), Community Member, 190 Posts

I need to figure out how to do a Store Locator with Address or Zip Code input (and just list out the stores in simple text) or preferably implement the [url=]Google Map Store Locator[/url].

It seems all the code is there for the Google example, I just need help translating that into SilverStripe.

I have a StoreLocationsPage and am using the DataObjectManager module to add Stores with this information: Store ID, Address, City, State, Zip, & maybe Latitude & Longitude.

1. Create markers table
I assume this means:

class Markers extends DataObject {}

2. Populate table
Using DataObjectManager

3. Find nearby locations w/ MySQL
Not sure how to do this

4. Outputting XML with PHP
I think this is achieved with the api stuff placed in the DataObject (Markers)

static $api_access = true;
   function canEdit() {
      return true;
   function canView() {
      return true;
   function canCreate() {
      return true;

5. Creating the map
Don't understand what I need to do here also. There's mention of geocoding. It would be nice (but not necessary) if it used geocoding automatically, but nice if I enter Lat & Lng info into the DataObject, it would override the geocode (sometimes those red markers on the map aren't super accurate).



6 October 2009 at 1:24pm (Last edited: 5 November 2009 7:58pm), Community Member, 190 Posts

I know someone out there wants to help :-)

So at this point just to get started, I'm just trying to get a map with multiple markers with an Info Window for each. Once I get this, I'll try to add more functionality.

I've discovered that the XML that's being spit out of SS is incompatible with the Google map...


<DataObjectSet totalSize="4">
   <Marker href="http://localhost:-----/ss233/api/v1/Marker/1.xml">
      <Address>1521 1st Ave</Address>
      <MarkerPage linktype="has_one" href="http://localhost:-----/api/v1/MarkerPage/20.xml" id="20"></MarkerPage>

   <Marker href="http://localhost:-----/api/v1/Marker/2.xml">
      <Address>2222 2nd Ave</Address>
      <MarkerPage linktype="has_one" href="http://localhost----/api/v1/MarkerPage/20.xml" id="20"></MarkerPage>

Google XML needs all of the city, state, lat, lng to be in marker like this:

   <marker name="Pan Africa Market" address="1521 1st Ave, Seattle, WA" lat="30.0224" lng="-95.4248" type="restaurant"/>
   <marker name="Buddha Thai &amp; Bar" address="2222 2nd Ave, Seattle, WA" lat="47.613590" lng="-122.344391" type="bar"/>
   <marker name="The Melting Pot" address="14 Mercer St, Seattle, WA" lat="47.624561" lng="-122.356445" type="restaurant"/>
   <marker name="Ipanema Grill" address="1225 1st Ave, Seattle, WA" lat="47.606365" lng="-122.337654" type="restaurant"/>

Is there any way to modify this Google code so it will accept a differently formatted XML?

GDownloadUrl("api/v1/Marker", function(data) {
   var xml = GXml.parse(data);
    var markers = xml.documentElement.getElementsByTagName("marker","name","lat","lng","type");
    for (var i = 0; i < marker.length; i++) {
   var point = new GLatLng(parseFloat(marker.getElementsByTagName("lat")),
    var marker = createMarker(point, name, address, type);


6 October 2009 at 3:25pm Community Member, 283 Posts

Wag the tail, not the dog man!

Use a custom SS template to bend the data to a proper GData XML format. Instead of using the plain old getXML() output you will have to whip up a custom template and do:

return $this->customise($mydataobject)->renderWith('mysweetgdataxmltemplate');

More at


31 October 2009 at 7:42pm (Last edited: 31 October 2009 7:45pm), Community Member, 190 Posts

Thanks Dalesaurus,

Just to make sure I did this correctly, even with the renderWith line, I still have to create a page in the CMS, correct? And if I do that and set the page type to "My Sweet Gdata Xml Template" then what purpose does the renderWith serve (since I can delete it and it still works)?


So, to anyone that cares, this is how my final Map turned out:

- Used DataObjectManager to create the Store Locations (fields included: Address, City, State, Zip, Latitude, Longitude, Phone, Delivery Availability)
- I created a special XML template formatted so Google could read it.
- The Map is similar to the "Google Map Selection Field" but I did not use the module and just hard coded the form field in there.
- The map markers are color coded based on whether the store offered delivery
- The Info Windows on the Map Markers show some info and include a form for driving directions

-- I couldn't figure out the radius select and didn't try to do the sidebar list of stores
-- Also, couldn't figure out how to get driving directions to show up on the same page as the map ( kept getting "undefined locations" )


1 November 2009 at 7:39am Community Member, 283 Posts

Well you just need to correspond the output with a template. If you create a MySweetPagetype Page and corresponding template, it will be used automatically.

However you could just create a separate and create an action in Page.php then tell it to render with that specific template using renderWith.

public function getgdata() {
// Fetch data for map into array or
// ArrayData $data, depending on nesting complexity
return $this->customise($data)->renderWith('mysweetgdatatemplate');

Then you can just point your code to to fetch the XML, without fussing with pages in the CMS.


1 November 2009 at 7:30pm Community Member, 190 Posts

Guess I'm not doing something right...just get a Page Not Found instead of the XML page.


class StoreLocation extends DataObject {


class Page_Controller extends ContentController {
   public function gmapxml() {      
      return $this->customise('StoreLocation')->renderWith('GoogleMapXml');
      $this->getResponse()->addHeader('Content-Type', 'application/xml; charset="utf-8"');
(themes > mytheme > templates >


I really appreciate the help. Thank you.


2 November 2009 at 5:13am Community Member, 283 Posts

You're really close, just a few things out of order.

1. You are doing a return before you set your header (this ends execution of that function prematurely)
2. customise() requires an array keyed/valued like you would normally return to a custom template

class Page_Controller extends ContentController {
public function gmapxml() {
// Change this to get as many of whatever type you want
// Heck you can even use $this->URLParams to get stuff like
// gmapxml/food/34 to pass in IDs or the like

$storeLoc = DataObject::get('StoreLocation','filter stuff');
$data = array('Stores' => $storeLoc); // You will use this as $Stores in your template
$this->getResponse()->addHeader('Content-Type', 'application/xml; charset="utf-8"');
return $this->customise($data)->renderWith('GoogleMapXml');


3 November 2009 at 1:37pm Community Member, 190 Posts

hmmm....still getting a page not found...
Is there something I need to add to allow a function's name (gmapxml) to be used in the URL?

Go to Top