Drupal 5 Custom GMap Node

25 Mar 2008

I really enjoy Google Maps. And though they keep a little for themselves, the Google Maps API offers a really easy way to embed these maps into your own personal site. Fortunately for us Drupal users, the swell folks at the Chicago Technology Cooperative and the other wonderful open-source developers have put together an amazing module called GMap that integrates well with Location, Views, and even CCK (sort of). I have recently set up this site to use the GMAP module. And since this module is still not had a stable release yet, I figured I would explain what I have done with this site to get some custom maps on each node. I will go through setting up CCK fields, custom theming, and some extras.

In Action

First, have a gander at what this will look like once we are done.


Given that I already have a bunch of nodes to create a Map View with, I want to also display a map on each of the nodes for that location or place. I also want the node maps to be customize for each node. The main reason I would like this functionality is because I think in the context of a node that is a location, it should have a map with the node itself. Also, I think its a really nice feature to have control how that map looks. There are certain locations that I would like to be zoomed in real close, or that I want a map view, or a satellite view. This will give us that control.


The following is a list of assumptions in this process. If the following are not true, then this tutorial may not work for you.

GMap Bugs

There a couple things to note about this version of the GMap Module:
  • You will need to hack the GMap Module so that it uses the most recent stable version of the Google Maps API. See http://drupal.org/node/231473.
  • There are some inconsistencies between the API.txt file and the actual way to use the GMap API. See http://drupal.org/node/236352 for more information. For our purposes, the following needs to be noted for the associateive array that will be used to create each map:
    • Use controltype instead of control.
    • Use maptype instead of type.

Map Content Type

The first thing we need to do is set up a custom Content Type. This is where CCK and Location are going to come in.

Locative Information

First ensure, that Locative Information is added. When creating the Content Type, it will be at the top of the form. It's kind of hard to notice. Make sure that Maximum number of locations allowed for this type. is at least 1 and Default number of location forms is also at least 1. Plaese note that this tutorial is assuming one location per node. This could easily be changed so that it handled more that one location. Enabling this Location information, will ensure that Latitude and Longitude are collected. Again this could be changed to CCK fields instead. [img_assist|nid=16|title=Screen: Locative Information on Content Type Creation|desc=Screenshot to point out where the Locative Information section is when creating a new Content Type.|link=none|align=left|width=570|height=379]

CCK Map Parameters

Now you will want to create a set of fields to represent your map parameters. You can add or remove the ones you want. You will want to look at the GMap Macro Creator page that comes with GMap. Here is a brief description of my fields:
CCK Map Macro Parameters
NameMachine NameTypeWidget Type
Map Widthfield_cck_txt_map_widthTextText Field
Map Heightfield_cck_txt_map_heightTextText Field
Markerfield_cck_select_markerTextSelect List
Magnificationfield_cck_select_magnificationTextSelect List
Control Typefield_cck_select_map_controlTextSelect List
Map Typefield_cck_select_map_typeTextSelect List
[img_assist|nid=15|title=Screen: Macro Parameters as GMap Node Fields|desc=Screenshot of the CCK fields that are used to create a custom GMap per node.|link=none|align=left|width=570|height=395] The Select Lists should be filled appropriately from the GMap Macro Creator page. Hint: changes some values and note the macro at the bottom. Please note that these values are Case Sensitive.


Now that we have our content type set up, now we just have to determine how it is going to render all this information. Feel free to make a couple nodes with this new content type, as it will help you see what is happening.

Display Function

We will create a function in our template.php file, in our theme directory, so that calling the map in the theme will be simple.
#function to make Gmap macro data into a map
function your_theme_node_map_maker($id, $mark, $lat, $long, $zoom, $width, $height, $control, $map_type) {
    #intialize output
    $output = '';
    #put together array
    $arr_map = array(
        'id' => $id
        ,'zoom' => $zoom
        ,'width' => $width
        ,'height' => $height
        ,'latitude' => $lat
        ,'longitude'=> $long
        ,'maptype' => $map_type
        ,'controltype' => $control
        ,'markers' => array(
                'markername' => $mark
                ,'latitude' => $lat
                ,'longitude' => $long

    #display map through GMap theme function
    $output = theme('gmap', array('#settings' => $arr_map));
    #return output
    return $output;
} #end function
This should be pretty straightforward. It would not be too difficult to actually put this in the theme itself, but this way we could do some processing if necessary.

Calling the Function in the Theme

There is a couple ways to do this depending on how you like to make or edit themes. You can use the Content Template Module. But I like to stick with the traditional file method. Here is my sample node-ct-map.tpl.php file:
<?php if ($page == 0) { ?><h2 class="title"><a href="<?php print $node_url?>"><?php print $title?></a></h2><?php }; ?>

<div class="entry<?php if ($sticky) { print " sticky"; } ?>">
    <?php if ($picture) { print $picture; }?>

    <div class="ct-map-content"><?php print $node->content['body']['#value'] ?></div>
    <fieldset class="fieldgroup group-visits">
        <?php print alanpalazzolo_custom_visits($node->field_cck_date_location_start, $node->field_cck_txt_visited_descripti) ?>

    <?php if ($node->content['field_cck_img_map_images']['#value']) { ?>
    <fieldset class="fieldgroup group-map-pictures">
        <?php print $node->content['field_cck_img_map_images']['#value'] ?>
    <?php } ?>
        # Call Map Function
        # I have separated the parameters so that it easier to see
        print alanpalazzolo_custom_node_map_maker(
            $node->nid, $node->field_cck_select_marker[0]['view']
        ) ?>
    <?php print alanpalazzolo_custom_location($node->location) ?>


<div class="meta">
    <p class="byline"><?php print $submitted?></p>
    <?php if ($terms) { ?><p><span class="taxonomy"><?php print $terms?></span></p><?php }; ?>
    <?php if ($links) { ?><p class="links"><?php print $links?></p><?php }; ?>

Check Our Work

Now, when going to the nodes that we have created, there should be a map with the parameteres we have set on them. For instance:


This should be a fairly easy process. Create a new view.
  • Page Section
    • click Provide Page View
    • choose a URL
    • this is where the magic happens; under View Type choose GMap View
  • Fields Section
    • Location: Latitude
    • Location: Longitude (This is where the CCK fields could be substituted.)
    • I would also suggest choosing the Node: Title field so that there is link in each info bubble
  • Filter Section
    • Node: Published is Yes
    • Node: Type is One Of Map Type (This is the type that we defined above)


Please feel free to add a comment or contact me about this post. This is just a brief look into what can be done with these powerful technologies.
  Biking Awareness
Bruce Schneier: Security Theater Presentation