Displaying articles with tag

Making your mark on the World (rails with mappa - Part II)

Posted by nito, Mon Dec 31 02:28:00 UTC 2007

Now let’s look at adding markers, special google navigation controls, onload functionality and then let’s refactor and add a little Rails DRYness.

1) Adding a marker

Open map_controller.rb (you will find it in gmapping/app/controllers) in your favourite editor (no, let’s not go there!). Add the following method:

def marker
    @page_title = 'My first map with marker!'

    @gmap = Mappa::GMap.new()

    # the gmap api key for localhost:3000 - remember to change this!
    @gmap.api_key = "ABQIAAAArjtwNyA-0TDmcb74hMzhHBTJQa0g3IQ9GZqIMmInSLzwtGDKaBRSDWK-cqMmi3YB5dD-8a6Kwe1Qmg"
    @gmap.lat = 51.775362610
    @gmap.lng = -0.00100011

    # now for the lat and lng of the marker we want to add. 
    marker_lat = 51.78530
    marker_lng = -0.015
    #create our marker 
    marker = Mappa::GLatLng.new(:lat => marker_lat, :lng => marker_lng)

    #add the marker to the map.
    @gmap.add_marker(:point => marker)    
    @gmap.zoom = 12

    @gmap.onload = false

  end

Now let’s create the view file. This is very easy, because there are no changes to the file aside from the dynamically created javascript. By default, rails will look for a marker.rhtml file in gmapping/app/views/map. So, let’s copy our index.rhtml to marker.rhtml.

That’s it. go and try it.: http://localhost:3000/map/marker.

2) Adding google map controls and drying it up a bit

The method for adding controls is: Mappa.add_control(:control => ‘controltype’) The control can be one of: small, large, type, overview.

edit the map_controller.rb again and add the following lines to the bottom of the marker method you added (see above).

@gmap.add_control(:control => 'small')
    @gmap.add_control(:control => 'type')
    @gmap.add_control(:control => 'overview')

Because there was no difference between our index.rhtml and our marker.rhtml, we didn’t really need it, so let’s tell rails to render the same layout the for the marker method as we used for the index method. Add the following line to the very end of the method, just above the ‘end’ statement:

render :template => 'map/index'

Your marker method should now look like this:

def marker
    @page_title = 'My first map with marker!'

    @gmap = Mappa::GMap.new()

    # the gmap api key for localhost:3000 - remember to change this!
    @gmap.api_key = "ABQIAAAArjtwNyA-0TDmcb74hMzhHBTJQa0g3IQ9GZqIMmInSLzwtGDKaBRSDWK-cqMmi3YB5dD-8a6Kwe1Qmg"
    @gmap.lat = 51.775362610
    @gmap.lng = -0.00100011

    # now for the lat and lng of the marker we want to add. 
    marker_lat = 51.78530
    marker_lng = -0.015

    #create our marker 
    marker = Mappa::GLatLng.new(:lat => marker_lat, :lng => marker_lng)

    #add the marker to the map.
    @gmap.add_marker(:point => marker)    
    @gmap.zoom = 12

    @gmap.onload = false
    @gmap.add_control(:control => 'small')
    @gmap.add_control(:control => 'type')
    @gmap.add_control(:control => 'overview')

    render :template => 'map/index'

  end

Take another look: http://localhost:3000/map/marker

3) Getting it all out of the body, into the head and using onload (and introducing partials and helpers!)

To call something via onload in the header of our page, to actually include that content into the header section, and to keep it all nice and DRY requires a few new steps.

First let’s edit our layout file. open gmapping/app/views/layout/map.rhtml in your editor and replace the line that contains the body tag:

<body>

with

<%= body_tag_creator %>

the ‘body_tag_creator’ is something new: a helper method. change directory to: mapping/app/helpers and open the application_helper.rb file in your favourite editor, and add the body_tag_creator method. When you’ve finished, your file should look like this:

module ApplicationHelper

  def body_tag_creator
    if !@gmap.nil? && @gmap.onload
      '<body onload="' + @gmap.onload_func_name + '()" onunload="GUnload">'
    else
      '<body>'
    end
  end

end

This new method is now available to every view. We could also have restricted it to those views generated by the map_controller, by only adding it to the map_helper.rb. Helpers help us to keep view generating code out of our view files.

Add the following method to your map_controller.rb:

def marker_onload
    @page_title = 'My first map with marker!'

    @gmap = Mappa::GMap.new()

    # the gmap api key for localhost:3000 - remember to change this!
    @gmap.api_key = "ABQIAAAArjtwNyA-0TDmcb74hMzhHBTJQa0g3IQ9GZqIMmInSLzwtGDKaBRSDWK-cqMmi3YB5dD-8a6Kwe1Qmg"
    @gmap.lat = 51.775362610
    @gmap.lng = -0.00100011

    # now for the lat and lng of the marker we want to add. 
    marker_lat = 51.78530
    marker_lng = -0.015

    #create our marker 
    marker = Mappa::GLatLng.new(:lat => marker_lat, :lng => marker_lng)

    #add the marker to the map.
    @gmap.add_marker(:point => marker)    

    marker2_lat = 51.7900
    marker2_lng = -0.025

    #create our marker 
    marker2 = Mappa::GLatLng.new(:lat => marker2_lat, :lng => marker2_lng)

    #add the marker to the map.
    @gmap.add_marker(:point => marker2)    

    @gmap.zoom = 12

    @gmap.add_control(:control => 'large')
    @gmap.add_control(:control => 'type')
    @gmap.add_control(:control => 'overview')

  end

Now let’s create a new view, and in the process introduce the rails :partial template.

create a file called marker_onload.rhtml in gmapping/app/views/map. Edit that file and add the following layout:

<%= render :partial => 'headers' %>
<div style="height:400px;width:400px" id="gmap"></div>

That’s it for the view, now let’s look at the partial. The name of the partial, according to the render call in the marker_onload.rhtml file, is ‘headers’. All partial file names start with an underscore, so, create a file called _headers.rhtml in gmapping/app/views/map. Edit that file and add the following layout:

<% content_for :map_headers do %>
    <%= map_header(@gmap) %>
    <%= map_body(@gmap) %>
<% end %>

Why did we use a partial? Partials are generally used for small chunks of oft used code. In this case we are saving ourselves repetitive use of those four lines of markup, as it’s highly likely we will be using them again. Notice also, that the map_body mappahelper method is now included along with map_header in the section of the web page. We’re doing this because we are now going to be calling our map generating javascript from an onload that looks to the section for its code.

And that’s all for now folks. If you’ve been following along, you should be able to see what you’ve done by point your browser to: http://localhost:3000/map/marker_onload

Next: handling map events, creating more custom marker creation methods and reading from external .mjs files

0 comments | Filed Under: Geekliness Tutorial | Tags:

Hello World (rails with mappa - Part I)

Posted by nito, Sun Dec 30 20:57:00 UTC 2007

As promised, here’s the first in a little series of mappa.rb usage tutorials for Ruby on Rails.

These tutorials should provide something for all users, but for the sake of clarity and to help any rails virgin, I’ve written this tutorial in particular from the perspective of the beginner. So, we’re pretty much starting from the scratch. I’m assuming the you, the reader, aren’t a complete command line newbie, know how to use an editor of some sort and are familiar with command line navigation and command execution.

If you are not a beginner, ignore anything you consider beneath you and demonstrate your superior knowledge by just extracting the knowledge you require from the content below :-)..

Subsequent tutorials will make assumptions about your knowledge level based upon what you will have picked up already, and will probably assume “you already know it”, or have already read this tutorial.

Because I use OS X - a unix operating system, I’m using a Unix operating system in my examples. If you are using a non-unix based operating system, I recommend you translate my example command line instructions into those relevant to your operating system.

And, for the non-beginner (and beginner too!), I recommend you look at the forthcoming, more detailed, Mappa api article that will provide detail on all the key api methods.

[Clearly, you will need to have ruby and Ruby on Rails installed on your computer. Installation is beyond the scope of this article. For more information got to: Ruby on Rails]

Ready? Let’s begin!

1) Create a project and install the plugin

Enter the directory you wish to use to hold your rails project, copy the mappa.tar.gz file into that directory.

If you haven’t already downloaded it, go and get it from: Here.

Type or cut and paste the following code:


rails gmapping
cd gmapping/vendor/plugins
cp ../../../mappa.tar.gz .
tar xzvf mappa.tar.gz
cd ../..

This should leave us in the gmapping directory, ready to create a rails controller.

2) Create the controller.

In the top level gmapping directory, generate a map controller by typing the following:


ruby script/generate controller map index

Once you’ve done this, open a new shell, change to your gmapping directory and type:


ruby script/server

Once the server starts, open a browser and point it to http://localhost:3000/map You should see this:

Map#index Find me in app/views/map/index.rhtml

Clearly not what we want, yet… but we’re nearly there. First, let’s edit the controller, and then we’ll edit the view.

Change directory to the app/controllers directory (cd app/controllers should do it ;-) ). Using your favourite editor (really, whatever you want - this isn’t the place for editor wars. I’m a ‘textmate’ or ‘vi’ person myself, but you know, if you wish to twist your brain with emacs, that’s up to you.), open the map_controller.rb file and replace:

def index
  end

with this:

def index

    @page_title = 'Hello world!'

    #Create our new Gmap object
    @gmap = Mappa::GMap.new()

    # the gmap api key for localhost:3000 - remember to change this!
    @gmap.api_key = 'ABQIAAAArjtwNyA-0TDmcb74hMzhHBTJQa0g3IQ9GZqIMmInSLzwtGDKaBRSDWK-cqMmi3YB5dD-8a6Kwe1Qmg'

    # set the longitude and latitiude of the centre point of our map
    @gmap.lat = 51.775362610
    @gmap.lng = -0.00100011

    # set the zoom level of our map. This number is in the range of 1-18. 1 is lowest zoom and 18 is highest
    # we've picked a nice middling 12.
    @gmap.zoom = 12

    # by default gmap.onload is set to true. setting it to false allows (and expects)
    # you to want your javascript within the <body> section and not the <head>
    @gmap.onload = false

  end

Now we’re ready to create our view.

3) Create the view

First, we’re going to create a layout file. A layout is basically a special template that controls the global layout of our page: the html, the header and often the body definition, the kind of things that get repeated across many pages. Using the Google Maps API requires that we have a google map API key, so we are going to put that inside our layout file. Change into the app/views/layout directory and create a file called map.rhtml. edit that file, and add the following:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
  <head>
    <title><%= @page_title || 'map' %></title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <%= yield :map_headers %> 
  </head>
  <body>
    <%= yield %>
  </body>
</html>

Now, let’s create our action specific view. Change directory until you are in gmapping/app/views/map (cd ../map shoud do it ;-) ) open the index.rhtml file in an editor and replace :

<h1>Map#index</h1>
<p>Find me in app/views/map/index.rhtml</p>

with this:

<% content_for :map_headers do %>
    <%= map_header(@gmap) %>
<% end %>

<div style="height:400px;width:400px" id="gmap"></div>

<%= map_body(@gmap) %>

4) That’s all folks

No really. try it. http://localhost:3000/map. Go on, I dare you.

What did we just do??

“Whowa there.” I hear you say as, already, I’ve mired and obscured your beginners knowledge. What’s with that “content_for :map” jive?? Ah, yes. A little niftiness. As it says, it’s the content for map_headers. Pretty self explanatory, isn’t it? No? Scroll up a bit and look at the layout file. See the lines:

<head>
    <title><%= @page_title || 'map' %></title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <%= yield :map_headers %> 
  </head>

There you go. Your first rails trick. dynamically generating content for the containing layout using content_for. I’ll let you in on a secret: we don’t really need it here… but we will do… later… when we want to put all our javascript in the header section of our layout, dynamically.

Virtually Every rails template should contain a <%= yield %> line, and this is where the content generated for your view will end up. In our case, whatever is generated by the index.rhtml file is slotted in there EXCEPT that content generated by :

<% content_for :map_headers do %>
    <%= map_header(@gmap) %>
<% end %>

which ends up being picked up by the <%= yield :map_headers %> part of the rails template. What you see there is a call to a helper method that you get with mappa.rb, called map_header. map_header will then generate the relevant html header required (normally to include javascript files).

The

<%= map_body(@gmap) %>

line at the bottom of the index.rhtml did the rest of the dirty work. Another Mappa.rb helper method, map_body takes our @gmap variable, created in our index method in the controller, and generates the javascript required. This Javascript makes use of a div with the id of ‘gmap’ to act as the container for the map. This is the default value, but, as you’ll see in later tutorials, is easily cahnged. Now and finally, Take a look at the html source to see what it produced.

NEXT markers and onload

2 comments | Filed Under: Geekliness Tutorial | Tags: