Index: includes/common.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/common.inc,v
retrieving revision 1.1024
diff -u -p -r1.1024 common.inc
--- includes/common.inc	17 Oct 2009 05:50:27 -0000	1.1024
+++ includes/common.inc	17 Oct 2009 21:42:43 -0000
@@ -5101,6 +5101,9 @@ function drupal_common_theme() {
     'indentation' => array(
       'arguments' => array('size' => 1),
     ),
+    'template_variable_wrapper' => array(
+      'arguments' => array('content' => NULL, 'attributes' => array(), 'context' => array(), 'inline' => TRUE),
+    ),
     // from theme.maintenance.inc
     'maintenance_page' => array(
       'arguments' => array('content' => NULL, 'show_messages' => TRUE),
Index: includes/theme.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/theme.inc,v
retrieving revision 1.537
diff -u -p -r1.537 theme.inc
--- includes/theme.inc	16 Oct 2009 08:27:40 -0000	1.537
+++ includes/theme.inc	17 Oct 2009 21:42:44 -0000
@@ -2030,6 +2030,42 @@ function theme_indentation($variables) {
 }
 
 /**
+ * Wrap a template variable in an HTML element with the desired attributes.
+ *
+ * @param $variables
+ *   An associative array containing:
+ *   - content: A string of content to be wrapped.
+ *   - attributes: An array of attributes desired on the wrapping element (can
+ *     be passed to drupal_attributes()).
+ *   - context: An array of context information that can be used for customizing
+ *     the wrapping element. Contains the following keys:
+ *     - 'hook': The theme hook that will use the wrapped content.
+ *     - 'variable_name': The name of the variable within the theme hook that
+ *       will hold the wrapped content.
+ *     - 'variables': The array of variables in use by the theme hook.
+ *   - inline: TRUE if the content only contains inline HTML elements and
+ *     therefore can be validly wrapped by a 'span' tag. FALSE if the content
+ *     might contain block level elements and cannot be validly wrapped by a
+ *     'span' tag. Modules implementing preprocess functions that set
+ *     'variable_attributes_array' for block-level variables are also
+ *     responsible for implementing hook_preprocess_template_variable_wrapper()
+ *     that sets 'inline' to FALSE for that context.  
+ *
+ * @return
+ *   A string containing the wrapped content.
+ *
+ * @see template_process()
+ */
+function theme_template_variable_wrapper($variables) {
+  $output = $variables['content'];
+  if (!empty($output) && !empty($variables['attributes'])) {
+    $attributes = drupal_attributes($variables['attributes']);
+    $output = $variables['inline'] ? "<span$attributes>$output</span>" : "<div$attributes>$output</div>";
+  }
+  return $output;
+}
+
+/**
  * @} End of "defgroup themeable".
  */
 
@@ -2110,6 +2146,23 @@ function template_process(&$variables, $
   // Flatten out attributes and title_attributes.
   $variables['attributes'] = drupal_attributes($variables['attributes_array']);
   $variables['title_attributes'] = drupal_attributes($variables['title_attributes_array']);
+
+  // Modules may use variable_attributes_array to register attributes needed
+  // around a particular template variable. Themes need control over the
+  // markup element used for this (whether it's a div, span, or something else,
+  // and the class on it).
+  $variables['variable_attributes'] = array();
+  if (!empty($variables['variable_attributes_array'])) {
+    foreach ($variables['variable_attributes_array'] as $variable_name => $attributes_array) {
+      // Provide the flattened attributes for themes that want to wrap within
+      // the template.
+      $variables['variable_attributes'][$variable_name] = drupal_attributes($attributes_array);
+      // Wrap the variable directly, but via a theme function, so that themes
+      // can override the markup element used or return the variable unwrapped
+      // and wrap in the template instead.
+      $variables[$variable_name] = theme('template_variable_wrapper', array('content' => $variables[$variable_name], 'attributes' => $attributes_array, 'context' => array('hook' => $hook, 'variable_name' => $variable_name, 'variables' => $variables)));
+    }
+  }
 }
 
 /**
