Abstract Musings

Documenting the random thoughts of a cluttered mind

Using an Existing Field in Movable Type for the Flash Photoblog World Map

Last month, I added Mark Zeman’s Flash Photoblog World Map to my Photos section. When I originally put the map up, I used the admin tool which came with the map to add the map locations to a separate database. This required using two separate interfaces for each posting – not an ideal solution. So since then, I’ve been looking for a way to integrate the map with Movable Type.

One of the initial options I considered was to use an existing field for the extra information required by the map. This was the easiest option available. Unfortunately, it wasn’t really an option for me, since I was already using all of the fields for my posts. However, I’ve decided to explain how to do it, since it isn’t all that difficult. You can read the details about the more complex option I decided to use, but if the idea of adding columns to your database, or rummaging around in Perl code doesn’t appeal to you, then using an existing field is probably the solution for you.

The object of this post will be to help you implement this solution (using an existing field) for integrating the Flash Photoblog World Map into your MT installation. The main advantage to this approach, besides its simplicity, is that it requires no modification of your MT files or database. All that’s (possibly) required is an extra PHP file in the directory with your Flash Map and creating two templates. You’ll be using the PHP based version of the Flash Map, so you’ll need to have PHP on your server. If you don’t have PHP on your server you could try using Brad Choate’s Key Values plugin, which will let you store the data in one of your fields as key/value pairs and then extract that data into a MT template tag suitable for use in your MT templates.

Ok, let’s get started.

Create a template for the XML data

In this step you’ll create a template for the XML file containing the data for the Flash Photoblog World Map.

Create a new index template. Give it a descriptive name. Mine is called “Photo Map XML Data”. (Not original, I know, but it conveys what it is.) Make sure the output file points to the directory where you placed the Flash Photoblog World Map. The output file should be called “mapxml.php”. For my installation this value would be “/map/mapxml.php”. Check the box labeled “Rebuild this template automatically when rebuilding index templates”, if you want the XML file to be rebuilt whenever a new entry is posted. Add the following code to the “Template Body” section:

<?php
  require('map_func.php');

  echo '<?xml version="1.0" encoding="UTF-8"?>'."\n";
  echo '<datapacket>'."\n";
<MTEntries lastn="999">
<MTIfNonEmpty tag="MTEntryKeywords">
  $image = '<$MTEntryID$>.jpg';
  $mapdata = '<$MTEntryKeywords$>';
  list($mapname,$maplocation,$mapdate) = explode("|",$mapdata);
  echo '<row id="<$MTEntryID$>" name="'.$mapname.'" file="<$MTEntryID$>.jpg" url="<$MTEntryPermalink$>" location="'.$maplocation.'" date="'.$mapdate.'" latitude="'.get_latitude($image).'" longitude="'.get_longitude($image).'" />'."\n";
</MTIfNonEmpty>
</MTEntries>
  echo '</datapacket>';
?>

Save the template.

Notes on the XML document: I use the Entry IDs as row ids and as the image names. You can substitute any other names or ids you want, just make sure that the row ids for the XML file are unique and change the Template Tags where appropriate in the sample code above. Also, the example I’ve given above uses the Keywords field to hold the data for the Flash Map, if you want to use a different field, then just substitute that field’s MT Entry tag in the line of code $mapdata = '<$MTEntryKeywords$>';, so if you wanted to use the Excerpt field instead, the line would be $mapdata = '<$MTEntryExcerpt$>';. You can use any field you want to store the data, just modify that line accordingly. Also, I’ve included an MTIfNonEmpty tag with MTEntryKeywords as the attribute, so if the Keywords field is empty then no row will be added to the XML file for that post. This will allow the posting of entries that you don’t want to appear on the Flash Photoblog World Map, just keep the Keywords field blank when creating a new entry. Of course, this means that you can’t use the Keywords field in your regular entries, otherwise MT will put a row in the XML file for that entry. And if you’re using a different field, you’ll need to change that line as well.

One more thing: in the example above I’ve added some code to call a PHP script which extracts the GPS data from the EXIF data from the image (or images) and places that data in the XML file. The PHP script is available at http://robbyedwards.com/map/simple.zip. Just upload the map_func.php script from the zip file to the directory where your copy of the Flash Photoblog World Map is located. Note: this script requires the exif.php script and the makers directory from the Flash Photoblog World Map download be present in the same directory as your copy of the Flash Photoblog World Map. If you’d rather specify the GPS coordinates in your entries, then you can use the following code. You’ll just need to add the latitude and longitude in the Keywords field with the other data.

<?php
  echo '<?xml version="1.0" encoding="UTF-8"?>'."\n";
  echo '<datapacket>'."\n";
<MTEntries lastn="999">
<MTIfNonEmpty tag="MTEntryKeywords">
  $mapdata = '<$MTEntryKeywords$>';
  list($mapname,$maplocation,$mapdate,$maplatitude,$maplongitude) = explode("|",$mapdata);
  echo '<row id="<$MTEntryID$>" name="'.$mapname.'" file="<$MTEntryID$>.jpg" url="<$MTEntryPermalink$>" location="'.$maplocation.'" date="'.$mapdate.'" latitude="'.$maplatitude.'" longitude="'.$maplongitude.'" />'."\n";
</MTIfNonEmpty>
</MTEntries>
  echo '</datapacket>';
?>

Create a template for the Flash Photoblog Map

In this step you’ll create a template for a page containing the Flash Photoblog World Map.

Create another new index template. Give it a descriptive name. Mine is called “Photo Map”. (Again, not so creative, but well, that’s what it is.) As with the XML file, make sure the output file points to the directory where you placed the Flash Photoblog World Map. The output file can be called anything you want. For my installation this value would be “/map/keywords.php”. You can use any kind of file you want, though, so HTML files are fine; just use whatever extension you use for your regular MT posts. I left the box labeled “Rebuild this template automatically when rebuilding index templates” unchecked, since my page is static, but if you were including other information from your blog on this page you can check it. Next, add code to build a page for your template to the “Template Body” section. You’ll probably want to copy this code from another template, like your Main Index template. Just add the following code to the template where you want the map to appear.

<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0" width="600" height="318" id="map" align="middle"> <param name="allowScriptAccess" value="sameDomain" />
<param name="movie" value="map_php.swf" />
<param name="quality" value="high" />
<param name="bgcolor" value="#ffffff" />
<embed src="map_php.swf" quality="high" bgcolor="#ffffff" width="600" height="318" name="map" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" />
</object>

Save the template. Then rebuild it.

Create an entry

Create an new entry to your blog (or update an old one), adding the data for the Flash Map to it using the field you specified in your XML file. You’ll need to enter the data in the format name|location|date|latitude|longitude. (The latitude and longitude are not required if you are fetching them from the image’s EXIF data, just use the format name|location|date instead.) You must use use the pipe character (|) as a delimiter between each piece of data. For example, one of my entries would look like this A Day in the Everglades|Shark Valley, Everglades NP|November 27, 2004|25.759291666667|-80.766480555556. You can use another delimiter, if you want, just change the line list($mapname,$maplocation,$mapdate) = explode("|",$mapdata); (or list($mapname,$maplocation,$mapdate,$maplatitude,$maplongitude) = explode("|",$mapdata);, if you’re not reading the EXIF data for the latitude and longitude), specifying the new delimiter in the explode function. For example if you wanted to use an semicolon (;), then the line would look like list($mapname,$maplocation,$mapdate) = explode(";",$mapdata); (or list($mapname,$maplocation,$mapdate,$maplatitude,$maplongitude) = explode(";",$mapdata);, if you’re not reading the EXIF data for the latitude and longitude). Just be sure you aren’t using your chosen delimiter anywhere else in your data.

Ok, that’s it. When you save the new entry (or update an old one), check your map to see if it worked.

Download: http://robbyedwards.com/map/simple.zip – contains these instructions and the map_func.php script (for extracting the GPS data in the XML file).

You can see this in action at http://robbyedwards.com/map/mt/keywords.php. (Please note, I don’t use this method for my map, so this version is a static demo as of February 21, 2005. To see my real map, visit http://robbyedwards.com/map/.) If you use this method, please trackback this post, leave a comment, or email me to let me know how it worked. Any other comments, questions or feedback are also appreciated.