=== modified file 'docs/hooks.php'
--- docs/hooks.php	2009-09-29 18:52:40 +0000
+++ docs/hooks.php	2009-09-29 18:54:57 +0000
@@ -1375,6 +1375,17 @@
 }
 
 /**
+ * Add invoice templates to the list of suggested template files.
+ *
+ * @return
+ *   Array of template names that are available choices when mailing an
+ *   invoice.
+ */
+function hook_uc_invoice_templates() {
+  return array('admin', 'customer');
+}
+
+/**
  * Convenience function to display large blocks of text in several places.
  *
  * There are many instances where Ubercart modules have configurable blocks of

=== renamed file 'uc_order/templates/admin.itpl.php' => 'uc_order/templates/uc_order-admin.tpl.php'
--- uc_order/templates/admin.itpl.php	2009-07-24 17:06:02 +0000
+++ uc_order/templates/uc_order-admin.tpl.php	2009-09-29 17:50:59 +0000
@@ -8,10 +8,10 @@
 ?>
 
 <p>
-<?php echo t('Order number:'); ?> [order-admin-link]<br />
-<?php echo t('Customer:'); ?> [order-first-name] [order-last-name] - [order-email]<br />
-<?php echo t('Order total:'); ?> [order-total]<br />
-<?php echo t('Shipping method:'); ?> [order-shipping-method]
+<?php echo t('Order number:'); ?> <?php echo $order_admin_link; ?><br />
+<?php echo t('Customer:'); ?> <?php echo $order_first_name; ?> <?php echo $order_last_name; ?> - <?php echo $order_email; ?><br />
+<?php echo t('Order total:'); ?> <?php echo $order_total; ?><br />
+<?php echo t('Shipping method:'); ?> <?php echo $order_shipping_method; ?>
 </p>
 
 <p>
@@ -43,5 +43,5 @@
 
 <p>
 <?php echo t('Order comments:'); ?><br />
-[order-comments]
+<?php echo $order_comments; ?>
 </p>

=== renamed file 'uc_order/templates/customer.itpl.php' => 'uc_order/templates/uc_order-customer.tpl.php'
--- uc_order/templates/customer.itpl.php	2009-09-21 14:13:04 +0000
+++ uc_order/templates/uc_order-customer.tpl.php	2009-09-29 17:50:25 +0000
@@ -17,16 +17,16 @@
             <table width="100%" style="font-family: verdana, arial, helvetica; font-size: small;">
               <tr>
                 <td>
-                  [site-logo]
+                  <?php echo $site_logo; ?>
                 </td>
                 <td width="98%">
                   <div style="padding-left: 1em;">
-                  <span style="font-size: large;">[store-name]</span><br />
-                  [site-slogan]
+                  <span style="font-size: large;"><?php echo $store_name; ?></span><br />
+                  <?php echo $site_slogan; ?>
                   </div>
                 </td>
                 <td nowrap="nowrap">
-                  [store-address]<br />[store-phone]
+                  <?php echo $store_address; ?><br /><?php echo $store_phone; ?>
                 </td>
               </tr>
             </table>
@@ -38,17 +38,17 @@
           <td>
 
             <?php if ($thank_you_message) { ?>
-            <p><b><?php echo t('Thanks for your order, [order-first-name]!'); ?></b></p>
+            <p><b><?php echo t('Thanks for your order, !order_first_name!', array('!order_first_name' => $order_first_name)); ?></b></p>
 
             <?php if (isset($_SESSION['new_user'])) { ?>
             <p><b><?php echo t('An account has been created for you with the following details:'); ?></b></p>
-            <p><b><?php echo t('Username:'); ?></b> [new-username]<br />
-            <b><?php echo t('Password:'); ?></b> [new-password]</p>
+            <p><b><?php echo t('Username:'); ?></b> <?php echo $new_username; ?><br />
+            <b><?php echo t('Password:'); ?></b> <?php echo $new_password; ?></p>
             <?php } ?>
 
             <p><b><?php echo t('Want to manage your order online?'); ?></b><br />
-            <?php echo t('If you need to check the status of your order, please visit our home page at [store-link] and click on "My account" in the menu or login with the following link:'); ?>
-            <br /><br />[site-login]</p>
+            <?php echo t('If you need to check the status of your order, please visit our home page at !store_link and click on "My account" in the menu or login with the following link:', array('!store_link' => $store_link)); ?>
+            <br /><br /><?php echo $site_login; ?></p>
             <?php } ?>
 
             <table cellpadding="4" cellspacing="0" border="0" width="100%" style="font-family: verdana, arial, helvetica; font-size: small;">
@@ -62,7 +62,7 @@
                   <b><?php echo t('E-mail Address:'); ?></b>
                 </td>
                 <td width="98%">
-                  [order-email]
+                  <?php echo $order_email; ?>
                 </td>
               </tr>
               <tr>
@@ -72,18 +72,18 @@
                     <tr>
                       <td valign="top" width="50%">
                         <b><?php echo t('Billing Address:'); ?></b><br />
-                        [order-billing-address]<br />
+                        <?php echo $order_billing_address; ?><br />
                         <br />
                         <b><?php echo t('Billing Phone:'); ?></b><br />
-                        [order-billing-phone]<br />
+                        <?php echo $order_billing_phone; ?><br />
                       </td>
                       <?php if (uc_order_is_shippable($order)) { ?>
                       <td valign="top" width="50%">
                         <b><?php echo t('Shipping Address:'); ?></b><br />
-                        [order-shipping-address]<br />
+                        <?php echo $order_shipping_address; ?><br />
                         <br />
                         <b><?php echo t('Shipping Phone:'); ?></b><br />
-                        [order-shipping-phone]<br />
+                        <?php echo $order_shipping_phone; ?><br />
                       </td>
                       <?php } ?>
                     </tr>
@@ -96,7 +96,7 @@
                   <b><?php echo t('Order Grand Total:'); ?></b>
                 </td>
                 <td width="98%">
-                  <b>[order-total]</b>
+                  <b><?php echo $order_total; ?></b>
                 </td>
               </tr>
               <tr>
@@ -104,7 +104,7 @@
                   <b><?php echo t('Payment Method:'); ?></b>
                 </td>
                 <td width="98%">
-                  [order-payment-method]
+                  <?php echo $order_payment_method; ?>
                 </td>
               </tr>
 
@@ -131,7 +131,7 @@
                         <b><?php echo t('Order #:'); ?></b>
                       </td>
                       <td width="98%">
-                        [order-link]
+                        <?php echo $order_link; ?>
                       </td>
                     </tr>
 
@@ -141,7 +141,7 @@
                         <b><?php echo t('Shipping Method:'); ?></b>
                       </td>
                       <td width="98%">
-                        [order-shipping-method]
+                        <?php echo $order_shipping_method; ?>
                       </td>
                     </tr>
                     <?php } ?>
@@ -151,7 +151,7 @@
                         <?php echo t('Products Subtotal:'); ?>&nbsp;
                       </td>
                       <td width="98%">
-                        [order-subtotal]
+                        <?php echo $order_subtotal; ?>
                       </td>
                     </tr>
 
@@ -192,7 +192,7 @@
                         <b><?php echo t('Total for this Order:'); ?>&nbsp;</b>
                       </td>
                       <td>
-                        <b>[order-total]</b>
+                        <b><?php echo $order_total; ?></b>
                       </td>
                     </tr>
 
@@ -256,7 +256,7 @@
 
                   <?php if ($help_text) { ?>
                   <p><b><?php echo t('Where can I get help with reviewing my order?'); ?></b><br />
-                  <?php echo t('To learn more about managing your orders on [store-link], please visit our <a href="[store-help-url]">help page</a>.'); ?>
+                  <?php echo t('To learn more about managing your orders on !store_link, please visit our <a href="!store_help_url">help page</a>.', array('!store_link' => $store_link, '!store_help_url' => $store_help_url)); ?>
                   <br /></p>
                   <?php } ?>
 
@@ -267,7 +267,7 @@
                   <?php } ?>
 
                   <?php if ($store_footer) { ?>
-                  <p><b>[store-link]</b><br /><b>[site-slogan]</b></p>
+                  <p><b><?php echo $store_link; ?></b><br /><b><?php echo $site_slogan; ?></b></p>
                   <?php } ?>
                 </td>
               </tr>

=== added file 'uc_order/templates/uc_order.tpl.php'
--- uc_order/templates/uc_order.tpl.php	1970-01-01 00:00:00 +0000
+++ uc_order/templates/uc_order.tpl.php	2009-09-29 19:53:16 +0000
@@ -0,0 +1,12 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * This file is a dummy template.
+ *
+ * It serves as a reminder to theme writers that they must have a
+ * uc_order.tpl.php file in their theme if they want to override the other
+ * order templates.
+ */
+

=== modified file 'uc_order/uc_order.admin.inc'
--- uc_order/uc_order.admin.inc	2009-09-23 18:23:18 +0000
+++ uc_order/uc_order.admin.inc	2009-09-29 18:26:58 +0000
@@ -1078,7 +1078,7 @@
   }
 
   if ($view == 'invoice') {
-    $output = uc_order_load_invoice($order, 'print', variable_get('uc_cust_order_invoice_template', 'customer'));
+    $output = theme('uc_order', $order, 'print', variable_get('uc_cust_order_invoice_template', 'customer'));
     $output .= '<div align="right" style="margin-top: 1em; margin-right: 1em;"><input type="button" value="'. t('Print invoice') .'" onclick="window.print();" /> '
               .'<input type="button" value="'. t('Close window') .'" onclick="window.close();" /></div>';
     print $output;
@@ -1680,7 +1680,7 @@
  * Display an invoice in the browser, convert it to PDF, or e-mail it as HTML.
  */
 function uc_order_invoice($order, $op = 'view') {
-  $output = uc_order_load_invoice($order, $op, variable_get('uc_cust_order_invoice_template', 'customer'));
+  $output = theme('uc_order', $order, $op, variable_get('uc_cust_order_invoice_template', 'customer'));
 
   if ($op == 'print') {
     print $output;

=== modified file 'uc_order/uc_order.ca.inc'
--- uc_order/uc_order.ca.inc	2009-09-16 18:28:32 +0000
+++ uc_order/uc_order.ca.inc	2009-09-29 17:51:15 +0000
@@ -1242,7 +1242,7 @@
     $recipients[] = trim($address);
   }
 
-  $settings['message'] = uc_order_load_invoice($order, $settings['view'], $settings['template']);
+  $settings['message'] = theme('uc_order', $order, $settings['view'], $settings['template']);
 
   if (empty($recipients)) {
     watchdog('ca', 'Attempted to e-mail an invoice with no recipient.', array(), WATCHDOG_ERROR);

=== modified file 'uc_order/uc_order.module'
--- uc_order/uc_order.module	2009-09-22 14:36:22 +0000
+++ uc_order/uc_order.module	2009-09-29 19:23:35 +0000
@@ -326,6 +326,11 @@
  */
 function uc_order_theme() {
   return array(
+    'uc_order' => array(
+      'template' => 'uc_order',
+      'path' => drupal_get_path('module', 'uc_order') .'/templates',
+      'arguments' => array('order' => NULL, 'op' => 'view', 'template' => 'customer'),
+    ),
     'uc_order_state_table' => array(
       'arguments' => array('form' => NULL),
     ),
@@ -529,7 +534,7 @@
       $message['headers']['Content-Type'] = 'text/html; charset=UTF-8; format=flowed';
       $message['subject'] = t('Your Order Invoice', array(), $langcode);
       $message['from'] = uc_store_email_from();
-      $message['body'][] = uc_order_load_invoice($params['order'], 'admin-mail', variable_get('uc_cust_order_invoice_template', 'customer'));
+      $message['body'][] = theme('uc_order', $params['order'], 'admin-mail', variable_get('uc_cust_order_invoice_template', 'customer'));
       break;
 
     // Setup a custom e-mail defined by an action on a predicate.
@@ -718,6 +723,13 @@
   return $messages;
 }
 
+/**
+ * Implementation of hook_uc_invoice_templates().
+ */
+function uc_order_uc_invoice_templates() {
+  return array('admin', 'customer');
+}
+
 /*******************************************************************************
  * Callback Functions, Forms, and Tables
  ******************************************************************************/
@@ -1513,92 +1525,81 @@
 /**
  * Load a formatted invoice with an order's data.
  */
-function uc_order_load_invoice($order, $op = 'view', $template = 'customer') {
-  static $invoice;
-
-  if (isset($invoice[$order->order_id][$template])) {
-    return $invoice[$order->order_id][$template];
-  }
-
-  $thank_you_message = FALSE;
-
-  $file = drupal_get_path('module', 'uc_order') .'/templates/'. $template .'.itpl.php';
-  if (file_exists($file)) {
-    switch ($op) {
-      case 'checkout-mail':
-        $thank_you_message = TRUE;
-      case 'admin-mail':
-        $help_text = TRUE;
-        $email_text = TRUE;
-        $store_footer = TRUE;
-      case 'view':
-      case 'print':
-        $business_header = TRUE;
-        $shipping_method = TRUE;
-        break;
-    }
-
-    $products = $order->products;
-    if (!is_array($products)) {
-      $products = array();
-    }
-
-    $line_items = $order->line_items;
-    $items = _line_item_list();
-    foreach ($items as $item) {
-      if (isset($item['display_only']) && $item['display_only'] == TRUE) {
-        $result = $item['callback']('display', $order);
-        if (is_array($result)) {
-          foreach ($result as $line) {
-            $line_items[] = array(
-              'line_item_id' => $line['id'],
-              'title' => $line['title'],
-              'amount' => $line['amount'],
-              'weight' => $item['weight'],
-              'data' => $item['data'],
-            );
-          }
+//function uc_order_load_invoice($order, $op = 'view', $template = 'customer') {
+function template_preprocess_uc_order(&$variables) {
+  $variables['thank_you_message'] = FALSE;
+
+  switch ($op) {
+    case 'checkout-mail':
+      $variables['thank_you_message'] = TRUE;
+    case 'admin-mail':
+      $variables['help_text'] = TRUE;
+      $variables['email_text'] = TRUE;
+      $variables['store_footer'] = TRUE;
+    case 'view':
+    case 'print':
+      $variables['business_header'] = TRUE;
+      $variables['shipping_method'] = TRUE;
+      break;
+  }
+
+  $variables['products'] = $variables['order']->products;
+  if (!is_array($variables['products'])) {
+    $variables['products'] = array();
+  }
+
+  $variables['line_items'] = $variables['order']->line_items;
+  $items = _line_item_list();
+  foreach ($items as $item) {
+    if (isset($item['display_only']) && $item['display_only'] == TRUE) {
+      $result = $item['callback']('display', $variables['order']);
+      if (is_array($result)) {
+        foreach ($result as $line) {
+          $variables['line_items'][] = array(
+            'line_item_id' => $line['id'],
+            'title' => $line['title'],
+            'amount' => $line['amount'],
+            'weight' => $item['weight'],
+            'data' => $item['data'],
+          );
         }
       }
     }
-    if (!is_array($line_items)) {
-      $line_items = array();
-    }
-    usort($line_items, 'uc_weight_sort');
-
-    ob_start();
-    require($file);
-    $output = ob_get_contents();
-    ob_end_clean();
-  }
-
-  $output = token_replace($output, 'global');
-  $output = token_replace($output, 'order', $order);
-
-  $invoice[$order->order_id][$template] = $output;
-  return $output;
+  }
+  if (!is_array($variables['line_items'])) {
+    $variables['line_items'] = array();
+  }
+  usort($variables['line_items'], 'uc_weight_sort');
+
+  $types = array(
+    //'global' => NULL,
+    'order' => $variables['order'],
+  );
+
+  $full = new stdClass();
+  $full->tokens = $full->values = array();
+  foreach ($types as $type => $object) {
+    $temp = token_get_values($type, $object, FALSE, $options);
+    $full->tokens = array_merge($full->tokens, $temp->tokens);
+    $full->values = array_merge($full->values, $temp->values);
+  }
+
+  foreach ($full->tokens as $key => $token) {
+    $value = $full->values[$key];
+    $variables[str_replace('-', '_', $token)] = $value;
+  }
+
+  $variables['template_file'] = 'uc_order-'. $variables['template'];
 }
 
 /**
  * Return an array of invoice templates found in ubercart/uc_order/templates.
  */
 function uc_invoice_template_list() {
-  static $templates = array();
-
-  // If the template list hasn't already been loaded...
-  if (empty($templates)) {
-    // Get the path to the templates directory.
-    $dir = drupal_get_path('module', 'uc_order') .'/templates';
-
-    // Loop through all the files found in the directory.
-    foreach (file_scan_directory($dir, '.*\.itpl\.php', array('.', '..', 'CVS'), 0, FALSE) as $file) {
-      // Add them by name to the templates array, trimming off the extension.
-      $templates[] = substr($file->name, 0, strlen($file->name) - 5);
-    }
-
-    // Sort the template names alphabetically.
-    sort($templates);
-  }
+  $templates = drupal_map_assoc(module_invoke_all('uc_invoice_templates'));
+
+  // Sort the template names alphabetically.
+  sort($templates);
 
   return $templates;
 }

