Creating a Google Map with ExpressionEngine

As Richard Tape has begun to show in his part 1 and part 2 articles on Becoming an ExpressionEngine Superstar, EE is a flexible and easy to customize CMS. Now that everyone has some understanding of how EE works, I thought I would take this opportunity to show a relatively real world example of creating a dynamic Google Map powered by EE.

Final Product

For this example, let’s assume that our company has various locations throughout the US, and we are tasked with creating a Google Map that shows all the locations and is easy to maintain. Take a look at the demo to see what we are trying to accomplish.

Setting Up the Weblog and Custom Field Group

First, remember that a weblog is nothing more than just a container of data. Actually, in EE 2.0, they are changing the term weblog to channel. So we are going to create a weblog called Locations and a custom field group called Locations. It’s definitely not a requirement to have them be named the same, but it just makes it easier to understand the relationship.

Defining the Custom Field Group

I actually like to create the field group first, so let’s do that by going to Admin > Weblog Administration > Custom Weblog Fields. Then click on the big green button that says Create a New Weblog Field Group.

New Field Group

Field Groups

Enter Locations as the Field Group Name and click submit.

New Field Group

Naming the new field group

After you click submit, you will see that EE tells you that you can’t use it until you assign it to a weblog. But, we will assign it to a weblog when we create the weblog.

New Field Group Created

The Locations field group has been created

Now that our field group is created, we need to think about the actual fields that we want to have in it. The following are the fields that I think fit, and their properties in EE:

  1. Field Label: Longitude
    • Field Name: locations_longitude
    • Field Type: Text Input
    • Maxlength: 50
    • Default Text Formatting: None
    • Hide Formatting Menu
    • Required Field? Yes
  2. Field Label: Latitude
    • Field Name: locations_latitude
    • Field Type: Text Input
    • Maxlength: 50
    • Default Text Formatting: None
    • Hide Formatting Menu
    • Required Field? Yes
  3. Field Label: Address
    • Field Name: locations_address
    • Field Type: Text Input
    • Maxlength: 200
    • Default Text Formatting: None
    • Hide Formatting Menu
    • Required Field? Yes
  4. Field Label: Photo
    • Field Name: locations_photo
    • Field Type: Text Input
    • Maxlength: 50
    • Default Text Formatting: None
    • Hide Formatting Menu
    • Required Field? No
  5. Field Label: Photo Width
    • Field Name: locations_photo_width
    • Field Type: Text Input
    • Maxlength: 4
    • Default Text Formatting: None
    • Hide Formatting Menu
    • Required Field? No
  6. Field Label: Photo Height
    • Field Name: locations_photo_height
    • Field Type: Text Input
    • Maxlength: 4
    • Default Text Formatting: None
    • Hide Formatting Menu
    • Required Field? No
  7. Field Label: Description
    • Field Name: locations_description
    • Field Type: Textarea
    • Textarea Rows: 6
    • Default Text Formatting: XHTML
    • Display Formatting Menu
    • Required Field? No

Now that we have mapped out our fields, we need to create the fields in EE. So first, click on Add/Edit Custom Fields in the Locations record. Then, click on the big green button that says Create a New Custom Field.

Custom Fields

Click on Create a New Custom Field

Now here is where we create the fields in EE that we defined previously. First, let’s start with the Longitude field:

New Custom Field

Defining the Longitude field

Once we have selected all of the appropriate properties, click submit. Now, the Longitude field is created.

Custom Field Created

The Longitude field is created

Now that you have seen how to create one field, I’m just going to go ahead and create the rest.

Custom Fields Created

All custom fields created

Create the Locations Weblog

Now that our field group has been defined, we need to create our weblog and assign the Locations custom field group to it. First, click on the Weblog Administration bread crumb. Then click on Weblog Management. Finally, click the big green button that says Create a New Weblog.

Weblog Management

Weblog Management

Enter Locations as the Full Weblog Name and locations as the Short Name. Select Yes for Edit Group Preferences, and a new section will show up. This is where we select Locations as the Field Group.

Create New Weblog

Create Locations Weblog

Once all the settings have been select, click submit, and the Locations weblog is created.

Weblog Created

Locations Weblog Created

Entering Locations

Now that our Locations weblog is created, we can start to enter the locations. Hover over the Publish tab and click on Locations.

Locations Entry Form

Locations Entry Form

The Title, Address, and Description fields are pretty self explanatory, but the URL Title, Longitude, Latitude, and Photo fields may need a little explanation.

URL Title

The URL Title field is auto-populated when you enter the Title. The URL Title replaces spaces with underscores and makes the text lowercase. For this certain situation, we are not going to use it. There is a way to hide it, but I’m not going to go through that right now.

Longitude and Latitude

I’m sure everyone knows what longitude and latitude are, but the question is: how do you determine it from an address? By using a third party site like Map Builder. This site allows you to enter an address, and it returns the longitude and latitude.

Map Builder

Using Map Builder to get longitude and latitude

Photo

If we had a photo of the location, we can include it in when the plot point is clicked. Uploading images in EE can be a little confusing, so let’s walk through it.

First, click on the Upload File link which is located under the submit button. A pop-up window will come up.

File Upload

File Upload

Browse for your file on your computer, and click Submit.

You can resize the photo after uploading it by clicking the Resize Image button, but I sized my image before uploading, so I won’t demo that part. We want to select URL Only for the File Type and Photo for the Image Location.

File Uploaded

File Uploaded

Once our options have been selected, click on Place Image and Close Window. This will now populate your Photo field with the location of your image.

Photo Width and Height

If a user uploads a photo of the location, we want them to input the image height and width. If they do not, the image will break out of the information bubble because of how Google Maps calculates the size of the bubble. It is simple enough to add in the width and height to solve this problem, so we added that in.

Description

If we want to enter a brief description to display in the bubble when the plot point is clicked, this is where you would enter it. This field supports HTML formatting by default.

Now that we have entered all of our pieces of data, we can submit the form and the location will be published.

File Uploaded

Our Completed Entry

Then, just repeat this process for the additional entries.

Creating the Map

First, we need to create a new template group for our locations map by clicking on the Templates tab. Then, click on the big green button that says Create a New Template Group.

Templates

Templates

Then, enter locations into the Template Group name field, and click submit. Our template group has now been created.

Template Group Created

Template Group Created

While we are here, let’s make another template group called scripts.

Next, select the locations template group from the left hand column, and click on index. Now we can start to build our template. You will presented with what is just an empty box, this is where you will add all of your code.

Edit Template

Editing Templates

Now all we need to do is enter our code and click update, and our template is updated.

The Code

In order to use the Google Maps API, you need to sign up for an API key for your site. Once you sign up, you will be provided with the API key, which you use when including the JavaScript on the page. Let’s get started with a simple page and include our Google Maps code:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Locations</title>
<script src="http://maps.google.com/maps?file=api&v=2&sensor=false&key=ABQIAAAAGbpRl2XCyCtoHtEtVLA9mhT9xvUTfY2sa86RDF1pWLQtRVPGPxQD1aEASfi1xtt39RqVCDd8ib1hGw" type="text/javascript"></script>
</head>

<body>

</body>
</html>

Note: ABQIAAAAGbpRl2XCyCtoHtEtVLA9mhT9xvUTfY2sa86RDF1pWLQtRVPGPxQD1aEASfi1xtt39RqVCDd8ib1hGw is the value of the Google Maps API key for my site. You will need to update this with your own key.

Once this code has been entered into to textarea, just click update to save the template. Then, if you click the big green button that says View Rendered Template, we will see what the page will look like.

Next, we need to add a div that will actually contain the map.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Locations</title>
<script src="http://maps.google.com/maps?file=api&v=2&sensor=false&key=ABQIAAAAGbpRl2XCyCtoHtEtVLA9mhT9xvUTfY2sa86RDF1pWLQtRVPGPxQD1aEASfi1xtt39RqVCDd8ib1hGw" type="text/javascript"></script>
</head>

<body>

<div id="map">You must have JavaScript Enabled to view this map.</div>

</body>
</html>

Note: I just added the message about needing JavaScript for the users who do not have JavaScript enabled, but you could certainly output the list of locations instead of this message.

We need to define the height and width of the div that is going to contain the map, so for this example, I am just going to use some CSS on the page.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Locations</title>
<script src="http://maps.google.com/maps?file=api&v=2&sensor=false&key=ABQIAAAAGbpRl2XCyCtoHtEtVLA9mhT9xvUTfY2sa86RDF1pWLQtRVPGPxQD1aEASfi1xtt39RqVCDd8ib1hGw" type="text/javascript"></script>
<style type="text/css">
#map { height: 600px; width: 800px; }
</style>
</head>

<body>

<div id="map">You must have JavaScript Enabled to view this map.</div>

</body>
</html>

That is all of the HTML we need to get our map to show up, so once the code is entered, click Update and Finished, and we are taken back to the main templates section. Next, we are going to code our JavaScript to add the points to the map.

Select scripts from the left hand column and click on New Template. Enter map as the template name, and select JavaScript from the Template Type dropdown, and then click Submit.

Our new template named map has now been created. So click on map, and let’t edit the template.

The cool thing about EE is that we can enter EE code into the JS and CSS templates and it will process that code. In order to do this, we do have to add a hidden config variable to our config.php file that is located in the system folder. So open up your config.php file and enter the following: $conf['protect_javascript'] = ‘n’;. Then upload it, and EE tags will be processed in JS code.

Note: I am going to use plain old JavaScript for this example, but you could easily modify some code to use your framework of choice.

First, we are going to get started creating a function that will add the plot points to the map:

function populateMap() {
	var map = new GMap2(document.getElementById("map"));
	map.setCenter(new GLatLng(32.02670629333614, -95.009765625), 4);
	map.setUIToDefault();
}

The first line is specifying to use the element with an id of map to create the map. The next line sets the center of the map to the specified latitude and longitude, then sets the zoom level. These are just arbitrary values for this example, so you will most likely need to adjust. The final line sets up the controls on the map, i.e. zoom, move, map type, etc.

Now, we want to access the data that we entered in EE by using the exp:weblog:entries tag:

function populateMap() {
	var map = new GMap2(document.getElementById("map"));
	map.setCenter(new GLatLng(32.02670629333614, -95.009765625), 4);
	map.setUIToDefault();

	{exp:weblog:entries weblog="locations" disable="categories|category_fields|member_data|pagination|trackbacks"}
		{if count == 1}
			var points = new Array({total_results});
		{/if}

	{/exp:weblog:entries}
}

So this code is saying to “query” the locations weblog, and disable additional parameters that we will not be using. This is a good habit to get into because it can improve performance.

There are some EE variables that we are using that I will need to explain: count and total_results. count is exactly what it sounds like: it just indicates the number of the current record that we are on. total_results indicates how many total records will be returned.

So if count equals 1, this the first time through the loop, so we initialize our array that will have a size of the total number of records returned.

Next, we want to actually grab the data and output it in the loop. Note: I am going to add line breaks to this code just for readability, but in production use, the line breaks need to be removed.

function populateMap() {
	var map = new GMap2(document.getElementById("map"));
	map.setCenter(new GLatLng(32.02670629333614, -95.009765625), 4);
	map.setUIToDefault();

	{exp:weblog:entries weblog="locations" disable="categories|category_fields|member_data|pagination|trackbacks"}
		{if count == 1}
			var points = new Array({total_results});
		{/if}

		points[{count}] = [{locations_latitude},{locations_longitude},
			'<div class="infoContainer">
				<h2>{title}</h2>
				{if locations_photo && locations_photo_width && locations_photo_height}
					<img src="{locations_photo}" alt="" height="{locations_photo_height}" width="{locations_photo_width}" />
				{/if}
				<p class="address">{locations_address}</p>
				{if locations_description}
					{locations_description}
				{/if}
			</div>'];

	{/exp:weblog:entries}
}

That may look like a lot, so let’s go through it piece by piece.

points[{count}] = [{locations_latitude},{locations_longitude},

Here, we are adding an array to our points array. In this array, we are going to be adding the latitude, longitude, and information to display in the information bubble. Notice how locations_latitude and locations_longitude match up with the values we added for the Field Names in our custom field group.

'<div class="infoContainer">
	<h2>{title}</h2>
</div>'];

In this snippet, we are just adding a div and the title that was entered into EE.

{if locations_photo && locations_photo_width && locations_photo_height}
	<img src="{locations_photo}" alt="" height="{locations_photo_height}" width="{locations_photo_width}" />
{/if}

In this piece, we are checking to see if there was a value entered into the photo, photo width, and photo height fields. If there was, we add the photo to our information bubble.

<p class="address">{locations_address}</p>
{if locations_description}
	{locations_description}
{/if}

Finally, we add the address to the information bubble, and if there was a description entered, we add that too. Here is that whole line without any line breaks:

points[{count}] = [{locations_latitude},{locations_longitude},'<div class="infoContainer"><h2>{title}</h2>{if locations_photo && locations_photo_width && locations_photo_height}<img src="{locations_photo}" alt="" height="{locations_photo_height}" width="{locations_photo_width}" />{/if}<p class="address">{locations_address}</p>{if locations_description}{locations_description}{/if}</div>'];

To finish off the function, we just need to loop through the array and add the plot points and event listeners to the map:

function populateMap() {
	var map = new GMap2(document.getElementById("map"));
	map.setCenter(new GLatLng(32.02670629333614, -95.009765625), 4);
	map.setUIToDefault();

	{exp:weblog:entries weblog="locations" disable="categories|category_fields|member_data|pagination|trackbacks"}
		{if count == 1}
			var points = new Array({total_results});
		{/if}

		points[{count}] = [{locations_latitude},{locations_longitude},'<div class="infoContainer"><h2>{title}</h2>{if locations_photo && locations_photo_width && locations_photo_height}<img src="{locations_photo}" alt="" height="{locations_photo_height}" width="{locations_photo_width}" />{/if}<p class="address">{locations_address}</p>{if locations_description}{locations_description}{/if}</div>'];

	{/exp:weblog:entries}

	for(var i=1; i < points.length; i++) {
		var point = new GLatLng(points[i][0],points[i][1]);
		var windowInfo = points[i][2];
		var marker = createMarker(point,windowInfo);
		map.addOverlay(marker);
	}
}

So we are creating our point and passing in the latitude and longitude. Then, we are creating a variable that contains all of the information for the information bubble. Next, we are calling a custom function that I will define in a minute and passing in the point and information bubble text. Finally, we are adding the marker to the map.

Here is our custom function that is creating the marker:

function createMarker(point, overlayText) {
	var marker = new GMarker(point);
	GEvent.addListener(marker, "click", function() {marker.openInfoWindowHtml(overlayText);});
	return marker;
}

So we are creating a marker based on our point on the map, then adding an event listener that will open the information bubble with the appropriate text when it is clicked.

So that’s pretty much it. Although, I will add one more function that will tell the JS function to run once the dom has been loaded:

function addLoadEvent(func) {
	var oldonload = window.onload;
	if (typeof window.onload != 'function') {
		window.onload = func;
	} else {
		window.onload = function() {
			if (oldonload) {
				oldonload();
			}
			func();
		}
	}
}
addLoadEvent(populateMap);

I first read about this function from Simon Willison. You could again replace this with code for whatever JS library you are using.

Here is the full JS for that template:

function populateMap() {
	var map = new GMap2(document.getElementById("map"));
	map.setCenter(new GLatLng(32.02670629333614, -95.009765625), 4);
	map.setUIToDefault();

	{exp:weblog:entries weblog="locations" disable="categories|category_fields|member_data|pagination|trackbacks"}
		{if count == 1}
			var points = new Array({total_results});
		{/if}

		points[{count}] = [{locations_latitude},{locations_longitude},'<div class="infoContainer"><h2>{title}</h2>{if locations_photo && locations_photo_width && locations_photo_height}<img src="{locations_photo}" alt="" height="{locations_photo_height}" width="{locations_photo_width}" />{/if}<p class="address">{locations_address}</p>{if locations_description}{locations_description}{/if}</div>'];

	{/exp:weblog:entries}

	for(var i=1; i < points.length; i++) {
		var point = new GLatLng(points[i][0],points[i][1]);
		var windowInfo = points[i][2];
		var marker = createMarker(point,windowInfo);
		map.addOverlay(marker);
	}
}

function createMarker(point, overlayText) {
	var marker = new GMarker(point);
	GEvent.addListener(marker, "click", function() {marker.openInfoWindowHtml(overlayText);});
	return marker;
}

function addLoadEvent(func) {
	var oldonload = window.onload;
	if (typeof window.onload != 'function') {
		window.onload = func;
	} else {
		window.onload = function() {
			if (oldonload) {
				oldonload();
			}
			func();
		}
	}
}
addLoadEvent(populateMap);

Once all that code is added, click Update and Finished to be returned to the main templates page. Next, we need to go back to our locations template group and edit the index template.

We need to include the JS template that we just created in the head of the document:

<script type="text/javascript" src="{path="scripts/map"}"></script>

I am using the path variable to link to the JS template.

So now, when we go back and view our locations template in the browser, you may see a JS error. If a location description was entered, it may add some new lines to the code, so this will break the string in the JS. So the solution is to somehow remove those new lines.

Installing the Plugin

Luckily, there is a plugin for EE called Find and Replace that will let us replace all \n with nothing.

So browse to Admin > Utilities > Plugin Manager, and find the plugin in the right hand column. When you find it, click on install, and that’s it.

Using the Plugin

Now, we can use the plugin in our code. So go back and edit the map template in our scripts template group, and replace this:

{if locations_description}
	{locations_description}
{/if}

With this:

{if locations_description}
	{exp:replace find="\n" multiple="yes" regex="yes"}
		{locations_description}
	{/exp:replace}
{/if}

This function is basically just saying to replace all new lines with nothing. Of course we want to remove all of the line breaks from the code, so here is the updated full JS:

function populateMap() {
	var map = new GMap2(document.getElementById("map"));
	map.setCenter(new GLatLng(32.02670629333614, -95.009765625), 4);
	map.setUIToDefault();

	{exp:weblog:entries weblog="locations" disable="categories|category_fields|member_data|pagination|trackbacks"}
		{if count == 1}
			var points = new Array({total_results});
		{/if}

		points[{count}] = [{locations_latitude},{locations_longitude},'<div class="infoContainer"><h2>{title}</h2>{if locations_photo && locations_photo_width && locations_photo_height}<img src="{locations_photo}" alt="" height="{locations_photo_height}" width="{locations_photo_width}" />{/if}<p class="address">{locations_address}</p>{if locations_description}{exp:replace find="\n" multiple="yes" regex="yes"}{locations_description}{/exp:replace}{/if}</div>'];

	{/exp:weblog:entries}

	for(var i=1; i < points.length; i++) {
		var point = new GLatLng(points[i][0],points[i][1]);
		var windowInfo = points[i][2];
		var marker = createMarker(point,windowInfo);
		map.addOverlay(marker);
	}
}

function createMarker(point, overlayText) {
	var marker = new GMarker(point);
	GEvent.addListener(marker, "click", function() {marker.openInfoWindowHtml(overlayText);});
	return marker;
}

function addLoadEvent(func) {
	var oldonload = window.onload;
	if (typeof window.onload != 'function') {
		window.onload = func;
	} else {
		window.onload = function() {
			if (oldonload) {
				oldonload();
			}
			func();
		}
	}
}
addLoadEvent(populateMap);

Conclusion

That’s it! We can now view our template in the browser and see our EE powered Google Map. You can also view my demo.

Google Map



Add Comment

Discussion 62 Comments

  1. Sirwan says:

    first time im first. its annoying but irresistable.

  2. Andy Parsons says:

    This is great!

    I’m looking forward to seeing more EE tutorials in the coming months!

  3. Cool to see some EE posts over Nettus. Can’t wait for the next one!

  4. Greg says:

    Looks complicate to do something easy.

  5. Jeffrey Way says:
    Staff

    I agree. If you’re a big EE fan, tell your friends. If we develop enough of an EE following, I’m more than happy to post more and more EE tuts.

  6. Very cool, Cool Climate in Canada has extension for EE: Coollocation (http://coolclimate.ca/coollocation) that will actually Geocode right for you in the publish page, just specify the custom fields in the extension settings and your set!

    • Benjamin says:

      Nice! I was looking for something like this awhile back. thanks!

      Its too bad Cool Climate is going offline tho :(

  7. Lau says:

    Seems interesting… didnt read the entire article yet, but it might come in handy sometime.

  8. Caio Andrade says:

    Great article, Trevor…

    Very useful and easy…

    Congratulations

  9. MaxLazar says:

    2Austin Siewert: coollocation is no more support :( So now is more better to use SL Google Map – (http://tr.im/leEN) (with SAEF support)

  10. Jake says:

    I just finished a project in which I had to make a CMS type set up by hand. This would have accomplished the same task in an eighth of the time. Looks tempting. That “costing money” thing kind of make me cringe, but I think my time might be worth that much :-)

  11. Steve says:

    I can’t wait for EE 2.0 which is built on the codeigniter framework. I hope there will be some tutorials on that once it’s released.

  12. Tom says:

    Awesome stuff.

  13. clefevre says:

    I still like Mark Huot’s Geocoding Extension

    http://expressionengine.com/forums/viewthread/40657/

    • Trevor Davis says:
      Author

      I actually saw that extension after I wrote this article. Does it support adding multiple points to a map like I did? I didn’t see that explanation in the documentation and didn’t get around to installing it.

      • clefevre says:

        I have used it to create maps with multiple points using {fieldname_raw}{latitude}{longitude}’{/fieldname_raw} – with XML

      • Trevor Davis says:
        Author

        So does that mean that the user has to enter it in XML format? That doesn’t seem like an ideal situation for a non-savvy user.

      • clefevre says:

        I will contact you through your website to show you a couple examples of the way I did it. Everything I did was using Google’s example maps.

  14. Wes says:

    Here is a way easier way to accomplish this with EE.

    http://experienceinternet.co.uk/resources/details/sl-google-map/

    It uses Brandon Kelly’s FieldFrame Extension, which will completely change how you use EE 1.6+ if you are not using it already.

    • Wes says:

      Let me amend my comment…here is an easy way to accomplish something similar to his. You will not have the custom images per post with this straight out of the box.

      What I would probably do is create a single entry in EE called maps. Then using FieldFrame Matrix ( http://brandon-kelly.com/apps/fieldframe ), I would create columns for the longitude, latitude, address, picture etc.

      With FF Matrix, you will be able to add new rows, thus you can control all of your maps from a single weblog entry.

      If you still want to manage 1 map per weblog entry, I would still use FF Matrix and limit the and create columns for the longitude, latitude, etc. The advantage is that you will only be using one field type and thus only two columns in your weblog_data table in your database. MySQL has a limit on how many columns you use, so on large sites it is possible to run out of custom fields. You would be going from using 7 fields to as presented in the article to only using 1. Plus, you it won’t take as long to set up all of the fields!

  15. florian says:

    if you know basic EE its not complicated, However it looks time consuming :)

  16. A cool tut for expression engine. I might try downloading and experimenting with it.

    I’m sure you could do the same thing using a WordPress plugin or by using custom fields for latitude and longitude and a custom template which can be integrated with google maps.

    • Shane says:

      WordPress is incredibly versatile, but EE is a much cleaner solution for this type of thing, IMHO.

      Have you, or anybody else noticed that a lot of WordPress tutorials refer to ‘hacks’. Things rarely seem that clean when you want to do anything that complicated, and the PHP code is an absolute mess in many instances.

  17. I’m going to give this a try. I tried putting my own map together a while back but for whatever reason it only displays up to around 100 markers on the map. Never could figure out the problem.

    • Wes says:

      I think this might have to do with your weblog entries parameters in your template. By default, the weblog entries results are limited to displaying 100 entries. Just add something like limit=500 to up the entries displayed.

      Example:
      {exp:weblog:entries weblog=”[your weblog]” limit=”[your number]“}

      {/exp:weblog:entries}

  18. Josh says:

    Awesome! Thanks for this. I had a client asking for this exact thing about a week ago. So glad I can now deliver. Thanks TUTS!

  19. crysfel says:

    that was easy, just a CRUD and the google maps api but when you don´t know anything about EE it is complicated.

    have funnnnnnnn

  20. Andres says:

    Pretty cool Tutorial!! keep EE-Tutorials coming! there´s really a need for more info about EE.

  21. This is an awesome tutorial! Thanks so much!

  22. In regards to using a third party tool to determine the Latitude and Longitude, why now use this?
    Lifehacker – How to find latitude and longitude – Google http://bit.ly/17oNyu

    It’s a simple bookmarklet :)

  23. Wes says:

    You can use the Google Maps API to convert a string (normal) address to a Lat – Long location. I would much rather us this method instead of manually entering in the Lat – Long by hand.

    Here is how to do it.
    http://code.google.com/apis/maps/documentation/services.html#Geocoding_Object

  24. AMALTRA says:

    HI guys

    I am trying to print a pdf from close up of a whole city with google maps, maybe someone here knows how 2?

    sorry 4 posting, but its related :)

  25. mahalie says:

    I don’t get why you don’t just create a “my map” and embed it. Way easier!

    Mark Hout’s Geocode extension is great for adding a map to any post on the fly, supports multiple map points but not the image/detail stuff.

  26. Judd Lyon says:

    Keep the EE coming, as well as posts from Trevor.

  27. Adam says:

    Is there any way to use custom icons for the markers in this example? I know you can do this when pulling the info from a KML file.

  28. Great article. I’m currently using another way of creating google maps. This seems more involved but ultimately a more solid method. Thanks!

  29. sirisha. says:

    hii… i had seen the map that is created by you. its very good.
    can i have some help from you.
    i am doing project in data mining. for that we need to create a map for our own district.
    excepting reply from you.
    thanks in advance.

  30. kodegeek says:

    This is great post, that will be excellent if longitude, latitude can be find out automatically. I’m finding for that.

  31. Andy says:

    I definitely need to work on this. Thanks!

  32. John Faulds says:

    Better off using Mark Huot’s or nGen’s file extensions for uploading the images rather than using the native EE file uploader.

  33. Paul says:

    I struggling to get this to work, ive followed the tutorial but this is all im getting
    http://www.bacsol.co.uk/index.php/contact_us/test

    Javascript is enabled as the standard google map works here http://www.bacsol.co.uk/index.php/contact_us

    Anyone any ideas?

    • Dustin says:

      I had the same issue.

      I had to change my entry field parameter to “none” and make sure there was no white space in my entry fields.

      I also killed the description field and put all my info in the address field. I was getting an EE error with {exp:replace}

      Once that was done it worked fine.

      Good luck

    • Murat says:

      i’m having the exact same problem in my test page
      http://www.akik.tk/ee/

      I couldn’t understand how to do
      “I had to change my entry field parameter to “none” and make sure there was no white space in my entry fields.”

      and thanks for any extra help

  34. BL says:

    well, good tutorial for novice users..
    but little complicated for advanced users..

  35. Stinky35 says:

    This statement could be the beginning of a smashing training design that learners will use with joy and glee, instruction that will have them engaged and really learning. ,

  36. Kelvin15 says:

    A letter or phone call to the family is recommended so that teachers and families can agree on a mutually convenient time. ,

  37. Peter says:

    Great base for a bit of EE dev work : )

    Any ideas how I’d add in the javascript required to use my own custom icon?

  38. great tutorial
    Im a bit confused.

  39. Sachin says:

    Hi,

    I have add the same map procedure in my Expression engine and I am facing the problem is “You must have JavaScript Enabled to view this map..”.

    Can you please let me know what is the problem? I have already use the Find and Replace module too.

  40. Shane McC says:

    Would anyone have any clue how to implement the above example with Marker Manager?
    And if you are having javascript issues, check your html for small errors.

  41. Timo says:

    Thank you for this great tutorial.

    I was wondering if it would be possible to also output a list of the locations next to the map with links associated to the pins… so when you click on a title next to the map, that bubble would pop up in the map and be centered.

    That would be great.
    Any ideas how to achieve that are appreciated.

  42. muhin says:

    How to download EE?

  43. Houston says:

    How can I migrate this code to comply with Google Maps v3?

  44. Frank Me says:

    This article is a great example of why you shouldn’t use cheesy CMS platforms like “ExpressionEngine”… gimme a break… this shit looks complicated… with other CMS platforms like Joomla, you just click new map module and you’re done! None of this complicated crap…. my advice stay away from ExpressionEngine and other cheesy CMS platforms wannabes

  45. Andy Hu says:

    It’s way too complicated. If you want to do this with Drupal, all you need to do is to install 3-4 community modules and configure them. There’s no single line code needed!

  46. Gary says:

    I can’t get this to work in EE 2.1.3 — I constantly get “You must have JavaScript Enabled to view this map.”

    I had to hunt down an updated version of Find & Replace; I wonder if that matters?

Add a Comment

To add a code snippet to your comment, please wrap your code like so: <pre name="code" class="html">YOUR CODE</pre>. You can replace the class name with "js," "css," "sql," or "php." If there are any "<" or ">" within your code, please search and replace them with: &lt; and &gt; respectively.