diff --git includes/common.inc includes/common.inc
index 5b452b5..c3fc6ab 100644
--- includes/common.inc
+++ includes/common.inc
@@ -3747,6 +3747,51 @@ function drupal_render_children(&$element, $children_keys = NULL) {
 }
 
 /**
+ * Render and print an element.
+ *
+ * This is a brief alias for drupal_render(), to be used in templates, that also
+ * directly prints out the rendered output.
+ * The top level element is always rendered and printed. Subsequent elements are
+ * only printed if they haven't been printed before or have been re-enabled with
+ * show(). If passed a string instead of a renderable array it is also printed.
+ *
+ * @see drupal_render()
+ * @see show()
+ * @see hide()
+ */
+function render(&$element) {
+  if (is_array($element)) {
+    show($element);
+    print drupal_render($element);
+  }
+  else {
+    print $element;
+  }
+}
+
+/**
+ * Hide an element during rendering.
+ *
+ * @see render()
+ * @see show()
+ */
+function hide(&$element) {
+  $element['#printed'] = TRUE;
+  return $element;
+}
+
+/**
+ * Show a hidden or already printed element during rendering.
+ *
+ * @see render()
+ * @see hide()
+ */
+function show(&$element) {
+  $element['#printed'] = FALSE;
+  return $element;
+}
+
+/**
  * Function used by uasort to sort structured arrays by weight.
  */
 function element_sort($a, $b) {
diff --git includes/theme.inc includes/theme.inc
index 50e693b..bbd0f3f 100644
--- includes/theme.inc
+++ includes/theme.inc
@@ -1886,7 +1886,7 @@ function template_process(&$variables, $hook) {
 }
 
 /**
- * Process variables for page.tpl.php
+ * Preprocess variables for page.tpl.php
  *
  * Most themes utilize their own copy of page.tpl.php. The default is located
  * inside "modules/system/page.tpl.php". Look in there for the full list of
@@ -1898,11 +1898,8 @@ function template_process(&$variables, $hook) {
  * Any changes to variables in this preprocessor should also be changed inside
  * template_preprocess_maintenance_page() to keep all of them consistent.
  *
- * The $variables array contains two keys:
- * - 'page': the fully decorated page.
- * - 'content': the content of the page, already rendered.
- *
  * @see drupal_render_page
+ * @see template_process_page
  * @see page.tpl.php
  */
 function template_preprocess_page(&$variables) {
@@ -1910,11 +1907,6 @@ function template_preprocess_page(&$variables) {
   $variables['show_blocks'] = $variables['page']['#show_blocks'];
   $variables['show_messages'] = $variables['page']['#show_messages'];
 
-  // Render each region into top level variables.
-  foreach (system_region_list($GLOBALS['theme']) as $region_key => $region_name) {
-    $variables[$region_key] = empty($variables['page'][$region_key]) ? '' : drupal_render($variables['page'][$region_key]);
-  }
-
   // Add favicon.
   if (theme_get_setting('toggle_favicon')) {
     $favicon = theme_get_setting('favicon');
@@ -1928,10 +1920,10 @@ function template_preprocess_page(&$variables) {
 
   // Set up layout variable.
   $variables['layout'] = 'none';
-  if (!empty($variables['left'])) {
+  if (!empty($variables['page']['left'])) {
     $variables['layout'] = 'left';
   }
-  if (!empty($variables['right'])) {
+  if (!empty($variables['page']['right'])) {
     $variables['layout'] = ($variables['layout'] == 'left') ? 'both' : 'right';
   }
 
@@ -1950,7 +1942,6 @@ function template_preprocess_page(&$variables) {
   $variables['front_page']        = url();
   $variables['breadcrumb']        = theme('breadcrumb', drupal_get_breadcrumb());
   $variables['feed_icons']        = drupal_get_feeds();
-  $variables['head']              = drupal_get_html_head();
   $variables['language']          = $GLOBALS['language'];
   $variables['language']->dir     = $GLOBALS['language']->direction ? 'rtl' : 'ltr';
   $variables['logo']              = theme_get_setting('logo');
@@ -1960,9 +1951,6 @@ function template_preprocess_page(&$variables) {
   $variables['search_box']        = (theme_get_setting('toggle_search') ? drupal_render(drupal_get_form('search_theme_form')) : '');
   $variables['site_name']         = (theme_get_setting('toggle_name') ? variable_get('site_name', 'Drupal') : '');
   $variables['site_slogan']       = (theme_get_setting('toggle_slogan') ? variable_get('site_slogan', '') : '');
-  $variables['css']               = drupal_add_css();
-  $variables['styles']            = drupal_get_css();
-  $variables['scripts']           = drupal_get_js();
   $variables['tabs']              = theme('menu_local_tasks');
   $variables['title']             = drupal_get_title();
   // RDFa allows annotation of XHTML pages with RDF data, while GRDDL provides
@@ -2016,6 +2004,28 @@ function template_preprocess_page(&$variables) {
 }
 
 /**
+ * Process variables for page.tpl.php
+ *
+ * Perform final addition and modification of variables before passing into 
+ * the template. To customize these variables, call drupal_render() on elements 
+ * in $variables['page] during THEME_preprocess_page().
+ *
+ * @see template_preprocess_page()
+ * @see page.tpl.php
+ */
+function template_process_page(&$variables) {
+  // Render each region into top level variables.
+  foreach (system_region_list($GLOBALS['theme']) as $region_key => $region_name) {
+    $variables[$region_key] = drupal_render($variables['page'][$region_key]);
+  }
+
+  $variables['head']    = drupal_get_html_head();
+  $variables['css']     = drupal_add_css();
+  $variables['styles']  = drupal_get_css();
+  $variables['scripts'] = drupal_get_js();
+}
+
+/**
  * Generate an array of page template suggestions.
  *
  * @param $args
diff --git modules/node/node.module modules/node/node.module
index 4194214..53dac98 100644
--- modules/node/node.module
+++ modules/node/node.module
@@ -1247,18 +1247,6 @@ function template_preprocess_node(&$variables) {
     unset($node->content['links']);
   }
 
-  // Render taxonomy links separately.
-  $variables['terms']     = !empty($node->content['links']['terms']) ? drupal_render($node->content['links']['terms']) : '';
-
-  // Render all remaining node links.
-  $variables['links']     = !empty($node->content['links']) ? drupal_render($node->content['links']) : '';
-
-  // Render any comments.
-  $variables['comments']  = !empty($node->content['comments']) ? drupal_render($node->content['comments']) : '';
-
-  // Render the rest of the node into $content.
-  $variables['content'] = drupal_render($node->content);
-
   // Flatten the node object's member fields.
   $variables = array_merge((array)$node, $variables);
 
diff --git modules/node/node.tpl.php modules/node/node.tpl.php
index 36ad041..6376ad3 100644
--- modules/node/node.tpl.php
+++ modules/node/node.tpl.php
@@ -7,7 +7,8 @@
  *
  * Available variables:
  * - $title: the (sanitized) title of the node.
- * - $content: Node body or teaser depending on $teaser flag.
+ * - $content: An array of node items. Use render($content) to print them all, or 
+ *   print a subset such as render($content['field_example']).
  * - $comments: the themed list of comments (if any).
  * - $picture: The authors picture of the node output from
  *   theme_user_picture().
@@ -64,6 +65,10 @@
  * @see template_preprocess_node()
  * @see template_process()
  */
+ 
+// Uncomment the line below to see what variables are available in this template.
+// print '<pre>' . check_plain(print_r(get_defined_vars(), TRUE)) . '</pre>';
+
 ?>
 <div id="node-<?php print $node->nid; ?>" class="<?php print $classes ?> clearfix">
 
@@ -78,17 +83,17 @@
     <span class="submitted"><?php print $submitted ?></span>
   <?php endif; ?>
 
-  <?php if ($terms): ?>
-    <div class="terms terms-inline"><?php print $terms ?></div>
+  <?php if (!empty($content['links']['terms'])): ?>
+    <div class="terms terms-inline"><?php render($content['links']['terms']) ?></div>
   <?php endif;?>
   </div>
 
   <div class="content">
-    <?php print $content ?>
+    <?php hide($content['comments']); hide($content['links']); render($content); ?>
   </div>
 
-  <?php print $links; ?>
+  <?php print render($content['links']); ?>
 
-  <?php print $comments; ?>
+  <?php print render($content['comments']); ?>
 
 </div>
\ No newline at end of file
diff --git modules/system/page.tpl.php modules/system/page.tpl.php
index 0510d4a..21fc1c5 100644
--- modules/system/page.tpl.php
+++ modules/system/page.tpl.php
@@ -75,11 +75,11 @@
  * - $tabs: Tabs linking to any sub-pages beneath the current page (e.g., the view
  *   and edit tabs when displaying a node).
  * - $help: Dynamic help text, mostly for admin pages.
- * - $content: The main content of the current Drupal page.
+ * - $content: The main content of the current page.
  * - $feed_icons: A string of all feed icons for the current page.
- * - $left: The HTML for the left sidebar.
- * - $right: The HTML for the right sidebar.
- * - $highlight: The HTML for the highlighted content region.
+ * - $left: Items for the left sidebar.
+ * - $right: Items for the right sidebar.
+ * - $highlight: Items for the highlighted content region.
  *
  * Footer/closing data:
  * - $footer : The footer region.
@@ -90,6 +90,10 @@
  * @see template_preprocess_page()
  * @see template_process()
  */
+ 
+// Uncomment the line below to see what variables are available in this template.
+// print '<pre>' . check_plain(print_r(get_defined_vars(), TRUE)) . '</pre>';
+
 ?>
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN"
   "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">
diff --git modules/user/user-profile.tpl.php modules/user/user-profile.tpl.php
index 5398d00..e639568 100644
--- modules/user/user-profile.tpl.php
+++ modules/user/user-profile.tpl.php
@@ -8,27 +8,13 @@
  * This template is used when viewing a registered member's profile page,
  * e.g., example.com/user/123. 123 being the users ID.
  *
- * By default, all user profile data is printed out with the $user_profile
- * variable. If there is a need to break it up you can use $profile instead.
- * It is keyed to the name of each category or other data attached to the
- * account. If it is a category it will contain all the profile items. By
- * default $profile['summary'] is provided which contains data on the user's
- * history. Other data can be included by modules. $profile['user_picture'] is
- * available by default showing the account picture.
- *
- * Also keep in mind that profile items and their categories can be defined by
- * site administrators. They are also available within $profile. For example,
- * if a site is configured with a category of "contact" with
- * fields for of addresses, phone numbers and other related info, then doing a
- * straight print of $profile['contact'] will output everything in the
- * category. This is useful for altering source order and adding custom
- * markup for the group.
- *
- * To check for all available data within $profile, use the code below.
- *
- * @code
- *   print '<pre>'. check_plain(print_r($profile, 1)) .'</pre>';
- * @endcode
+ * Use render($user_profile) to print all profile items, or print a subset
+ * such as render($content['field_example']). Always call render($user_profile)
+ * at the end in order to print all remaining items. If the item is a category,
+ * it will contain all it's profile items. By default, $user_profile['summary']
+ * is provided which contains data on the user's history. Other data can be
+ * included by modules. $user_profile['user_picture'] is available
+ * for showing the account picture.
  *
  * @see user-profile-category.tpl.php
  *   Where the html is handled for the group.
@@ -36,14 +22,16 @@
  *   Where the html is handled for each item in the group.
  *
  * Available variables:
- *   - $user_profile: All user profile data. Ready for print.
- *   - $profile: Keyed array of profile categories and their items or other data
- *     provided by modules.
+ *   - $user_profile: An array of profile items. Use render() to print them.
  *   - TODO D7 : document $FIELD_NAME_rendered variables.
  *
  * @see template_preprocess_user_profile()
  */
+ 
+// Uncomment the line below to see what variables are available in this template.
+// print '<pre>' . check_plain(print_r(get_defined_vars(), TRUE)) . '</pre>';
+ 
 ?>
 <div class="profile">
-  <?php print $user_profile; ?>
+  <?php print render($user_profile); ?>
 </div>
diff --git modules/user/user.pages.inc modules/user/user.pages.inc
index def9e06..9284274 100644
--- modules/user/user.pages.inc
+++ modules/user/user.pages.inc
@@ -185,20 +185,11 @@ function user_view($account) {
  * The $variables array contains the following arguments:
  * - $account
  *
- * @see user-picture.tpl.php
+ * @see user-profile.tpl.php
  */
 function template_preprocess_user_profile(&$variables) {
   $account = $variables['elements']['#account'];
-
-  $variables['profile'] = array();
-  // Sort sections by weight
-  uasort($account->content, 'element_sort');
-  // Provide keyed variables so themers can print each section independently.
-  foreach (element_children($account->content) as $key) {
-    $variables['profile'][$key] = drupal_render($account->content[$key]);
-  }
-  // Collect all profiles to make it easier to print all items at once.
-  $variables['user_profile'] = implode($variables['profile']);
+  $variables['user_profile'] = $account->content;
 
   // Add $FIELD_NAME_rendered variables for fields.
   $variables += field_attach_preprocess('user', $account);
diff --git themes/garland/node.tpl.php themes/garland/node.tpl.php
index 7e7a6ed..73bd3dc 100644
--- themes/garland/node.tpl.php
+++ themes/garland/node.tpl.php
@@ -4,7 +4,6 @@
 <div id="node-<?php print $node->nid; ?>" class="<?php print $classes ?>">
 
 <?php print $picture ?>
-
 <?php if ($page == 0): ?>
   <h2><a href="<?php print $node_url ?>" title="<?php print $title ?>"><?php print $title ?></a></h2>
 <?php endif; ?>
@@ -14,21 +13,21 @@
   <?php endif; ?>
 
   <div class="content clearfix">
-    <?php print $content ?>
+    <?php hide($content['links']); hide($content['comments']); render($content); ?>
   </div>
 
   <div class="clearfix">
     <div class="meta">
-    <?php if ($terms): ?>
-      <div class="terms"><?php print $terms ?></div>
+    <?php if (!empty($content['links']['terms'])): ?>
+      <div class="terms"><?php render($content['links']['terms']) ?></div>
     <?php endif;?>
     </div>
 
-    <?php if ($links): ?>
-      <div class="links"><?php print $links; ?></div>
+    <?php if (!empty($content['links'])): ?>
+      <div class="links"><?php render($content['links']) ?></div>
     <?php endif; ?>
 
-    <?php print $comments; ?>
+    <?php render($content['comments']); ?>
 
   </div>
 
