Binary files views_bonus/export/images/kml.png and views_bonus_patched_b4/export/images/kml.png differ
diff -Nrwup views_bonus/export/views-bonus-export-kml.tpl.php views_bonus_patched_b4/export/views-bonus-export-kml.tpl.php
--- views_bonus/export/views-bonus-export-kml.tpl.php	1969-12-31 19:00:00.000000000 -0500
+++ views_bonus_patched_b4/export/views-bonus-export-kml.tpl.php	2009-08-24 13:51:07.000000000 -0400
@@ -0,0 +1,67 @@
+<?php
+// $Id$
+/**
+ * @file views-view-table.tpl.php
+ * Template to display a view as a table.
+ *
+ * - $title : The title of this group of rows.  May be empty.
+ * - $rows: An array of row items. Each row is an array of content
+ *   keyed by field ID.
+ * - $header: an array of haeaders(labels) for fields.
+ * - $themed_rows: a array of rows with themed fields.
+ * @ingroup views_templates
+ */
+
+// Short tags act bad below in the html so we print it here.
+print '<?xml version="1.0" encoding="UTF-8"?>';
+?>
+
+<?php
+print '<kml xmlns="http://www.opengis.net/kml/2.2">';
+?>
+
+<Document>
+<?php foreach ($themed_rows as $count => $row): ?>
+  <Placemark>
+  <?php foreach ($row as $field => $content):
+    $label = $header[$field] ? $header[$field] : $field;
+    /*
+    Skip output if the label is "extra".
+    This allows for multiple fields to be combined
+    via the views interface without printing
+    invalid elements to the KML file.
+    */
+    if ($label == "extra") {
+      //do nothing
+    }
+    else {
+      $is_a_point = FALSE;
+      if ($label == "coordinates") {
+        $is_a_point = TRUE;
+      }
+      if ($is_a_point) {
+        print "<Point>";
+      }
+      $is_description = FALSE;
+      if ($label == "description") {
+        $is_description = TRUE;
+      }
+      print "<". $label .">";
+      if ($is_description) {
+        print "<![CDATA[";
+      }
+      print $content;
+      if ($is_description) {
+        print "]]>";
+      }
+      print "</". $label .">";
+      if ($is_a_point) {
+        print "</Point>";
+      }
+    }
+    ?>
+  <?php endforeach; ?>
+  </Placemark>
+<?php endforeach; ?>
+</Document>
+</kml>
diff -Nrwup views_bonus/export/views_bonus_export.theme.inc views_bonus_patched_b4/export/views_bonus_export.theme.inc
--- views_bonus/export/views_bonus_export.theme.inc	2009-06-24 13:27:53.000000000 -0400
+++ views_bonus_patched_b4/export/views_bonus_export.theme.inc	2009-08-24 13:40:21.000000000 -0400
@@ -50,6 +50,14 @@ function template_preprocess_views_bonus
 }
 
 /**
+ * Preprocess kml output template.
+ */
+function template_preprocess_views_bonus_export_kml(&$vars) {
+  drupal_set_header('Content-Type: text/xml');
+  _views_bonus_export_shared_preprocess($vars);
+}
+
+/**
  * Preprocess xml output template.
  */
 function template_preprocess_views_bonus_export_xml(&$vars) {
diff -Nrwup views_bonus/export/views_bonus_export.views.inc views_bonus_patched_b4/export/views_bonus_export.views.inc
--- views_bonus/export/views_bonus_export.views.inc	2009-05-13 03:06:20.000000000 -0400
+++ views_bonus_patched_b4/export/views_bonus_export.views.inc	2009-08-24 13:41:55.000000000 -0400
@@ -71,6 +71,18 @@ function views_bonus_export_views_plugin
         'uses options' => TRUE,
         'type' => 'feed',
       ),
+      'views_kml' => array(
+        'title' => t('KML file'),
+        'help' => t('Display the view as a keyhole markup language file.'),
+        'path' => $path,
+        'handler' => 'views_bonus_plugin_style_export_kml',
+        'parent' => 'views_bonus_export',
+        'theme' => 'views_bonus_export_kml',
+        'uses row plugin' => FALSE,
+        'uses fields' => TRUE,
+        'uses options' => TRUE,
+        'type' => 'feed',
+      ),
     ),
   );
 }
diff -Nrwup views_bonus/export/views_bonus_plugin_style_export_kml.inc views_bonus_patched_b4/export/views_bonus_plugin_style_export_kml.inc
--- views_bonus/export/views_bonus_plugin_style_export_kml.inc	1969-12-31 19:00:00.000000000 -0500
+++ views_bonus_patched_b4/export/views_bonus_plugin_style_export_kml.inc	2009-08-24 13:44:11.000000000 -0400
@@ -0,0 +1,61 @@
+<?php
+// $Id$
+/**
+ * @file
+ * Plugin include file for export style plugin.
+ */
+
+/**
+ * Generalized style plugin for export plugins.
+ *
+ * @ingroup views_style_plugins
+ */
+class views_bonus_plugin_style_export_kml extends views_bonus_plugin_style_export {
+  /**
+   * Initialize plugin.
+   *
+   * Set feed image for shared rendering later.
+   */
+  function init(&$view, &$display, $options = NULL) {
+    parent::init($view, $display, $options = NULL);
+    $this->feed_image = drupal_get_path('module', 'views_bonus_export') . '/images/kml.png';
+  }
+
+  /**
+   * Set options fields and default values.
+   *
+   * @return
+   * An array of options information.
+   */
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['filename'] = array(
+      'default' => 'view-%view.kml',
+      'translatable' => FALSE,
+    );
+
+    return $options;
+  }
+
+  /**
+   * Options form mini callback.
+   *
+   * @param $form
+   * Form array to add additional fields to.
+   * @param $form_state
+   * State of the form.
+   * @return
+   * None.
+   */
+  function options_form(&$form, &$form_state) {
+    $form['filename'] = array(
+      '#type' => 'textfield',
+      '#title' => t('KML filename'),
+      '#default_value' => $this->options['filename'],
+      '#description' => t('The filename that will be suggested to the browser for downloading purposes. %view will be replaced with the view name.'),
+      '#process' => array('views_process_dependency'),
+      '#dependency' => array('edit-style-options-override' => array(FALSE)),
+    );
+  }
+}
