diff --git a/addressfield.module b/addressfield.module
index 177d92b..0448b84 100644
--- a/addressfield.module
+++ b/addressfield.module
@@ -245,10 +245,63 @@ function addressfield_theme() {
   $hooks['addressfield_container'] = array(
     'render element' => 'element',
   );
+  $hooks['addressfield_address'] = array(
+    'variables' => array('country' => NULL, 'administrative_area' => NULL, 'sub_administrative_area' => NULL, 'locality' => NULL, 'dependent_locality' => NULL, 'postal_code' => NULL, 'thoroughfare' => NULL, 'premise' => NULL, 'sub_premise' => NULL, 'organisation_name' => NULL, 'name_line' => NULL, 'first_name' => NULL, 'last_name' => NULL, 'data' => NULL),
+    );
   return $hooks;
 }
 
 /**
+ * Theme function for rendering an address.
+ *
+ * This is an alternative to Addressfield's plugin system for formatters. To
+ * use this theme function with fields, you must select the "Theme function"
+ * formatter for the field's "Manage Display" settings.
+ *
+ * @param $variables
+ *   An array containing the addressfield sub-fields.
+ */
+function theme_addressfield_address($variables) {
+  // Make each sub-field available as its own variable.
+  foreach ($variables as $key => $value) {
+    $$key = $value;
+  }
+  
+  $output = '';
+  // Render street block
+  if ($thoroughfare || $premise) {
+    $output .= '<div class="street-block">';
+    if ($thoroughfare) {
+      $output .= '<div class="thoroughfare">' . $thoroughfare . '</div>';
+    }
+    if ($premise) {
+      $output .= '<div class="premise">' . $premise . '</div>';
+    }
+    $output .= '</div>';
+  }
+  
+  // Render locality block
+  if ($locality || $administrative_area || $postal_code) {
+    $output .= '<div class="locality-block">';
+    if ($locality) {
+      $output .= '<span class="locality">' . $locality . '</span>';
+    }
+    if ($locality && $administrative_area) {
+      $output .= ', ';
+    }
+    if ($administrative_area) {
+      $output .= ' <span class="state">' . $administrative_area . '</span>';
+    }
+    if ($postal_code) {
+      $output .= ' <span class="postal-code">' . $postal_code . '</span>';
+    }
+    $output .= '</div>';
+  }
+  
+  return $output;
+}
+
+/**
  * Render a container for a set of address fields.
  */
 function theme_addressfield_container($variables) {
@@ -524,6 +577,10 @@ function addressfield_field_formatter_info() {
         'format_handlers' => array('address'),
       ),
     ),
+    'addressfield_themeable' => array(
+      'label' => t('Theme function'),
+      'field types' => array('addressfield'),
+    ),
   );
 }
 
@@ -534,6 +591,11 @@ function addressfield_field_formatter_settings_form($field, $instance, $view_mod
   $display = $instance['display'][$view_mode];
   $settings = $display['settings'];
 
+  // Only expose these settings for the "addressfield_default" formatter.
+  if ($display['type'] != 'addressfield_default') {
+    return;
+  }
+
   $element['use_widget_handlers'] = array(
     '#type' => 'checkbox',
     '#title' => t('Use the same configuration as the widget'),
@@ -582,6 +644,10 @@ function addressfield_field_formatter_settings_summary($field, $instance, $view_
   $display = $instance['display'][$view_mode];
   $settings = $display['settings'];
 
+  if ($display['type'] != 'addressfield_default') {
+    return;
+  }
+
   $summary = '';
 
   if ($settings['use_widget_handlers']) {
@@ -624,6 +690,11 @@ function addressfield_field_formatter_view($entity_type, $entity, $field, $insta
         $element[$delta] = addressfield_generate($address, $handlers, $context);
       }
       break;
+    case 'addressfield_themeable':
+      foreach ($items as $delta => $item) {
+        $element[$delta] = array('#markup' => theme('addressfield_address', $item));
+      }
+      break;
   }
 
   return $element;
