diff --git a/includes/theme.inc b/includes/theme.inc
index 79a9732c8d2ad443c67502b69754841b5b4e995b..4a58329ff82b6d890ba85176687c2aba3e0e0762 100644
--- a/includes/theme.inc
+++ b/includes/theme.inc
@@ -2257,6 +2257,10 @@ function template_preprocess(&$variables, $hook) {
   $variables['title_attributes_array'] = array();
   $variables['content_attributes_array'] = array();
 
+  // Initialize 'title_prefix' and 'title_suffix' renderable arrays.
+  $variables['title_prefix'] = array();
+  $variables['title_suffix'] = array();
+
   // Set default variables that depend on the database.
   $variables['is_admin']            = FALSE;
   $variables['is_front']            = FALSE;
diff --git a/modules/block/block.tpl.php b/modules/block/block.tpl.php
index beb54687b11fd32e99c5a9f3caf670dd77c2599b..ad09a1ea089e11cef7391ced145d6245bd539b1b 100644
--- a/modules/block/block.tpl.php
+++ b/modules/block/block.tpl.php
@@ -11,7 +11,6 @@
  * - $block->module: Module that generated the block.
  * - $block->delta: An ID for the block, unique within each module.
  * - $block->region: The block region embedding the current block.
- * - $contextual_links (array): An array of contextual links for the block.
  * - $classes: String of classes that can be used to style contextually through
  *   CSS. It can be manipulated through the variable $classes_array from
  *   preprocess functions. The default values can be one or more of the following:
@@ -19,6 +18,12 @@
  *   - block-[module]: The module generating the block. For example, the user module
  *     is responsible for handling the default user navigation block. In that case
  *     the class would be "block-user".
+ * - $title_prefix (array): An array containing additional output populated by
+ *   modules, intended to be displayed in front of the main title tag that
+ *   appears in the template.
+ * - $title_suffix (array): An array containing additional output populated by
+ *   modules, intended to be displayed after the main title tag that appears in
+ *   the template.
  *
  * Helper variables:
  * - $classes_array: Array of html class attribute values. It is flattened
@@ -38,13 +43,11 @@
 ?>
 <div id="block-<?php print $block->module . '-' . $block->delta; ?>" class="<?php print $classes; ?>"<?php print $attributes; ?>>
  
-<?php if (!empty($contextual_links)): ?>
-  <?php print render($contextual_links); ?>
-<?php endif; ?>
- 
+  <?php print render($title_prefix); ?>
 <?php if ($block->subject): ?>
   <h2<?php print $title_attributes; ?>><?php print $block->subject ?></h2>
 <?php endif;?>
+  <?php print render($title_suffix); ?>
 
   <div class="content"<?php print $content_attributes; ?>>
     <?php print $content ?>
diff --git a/modules/comment/comment.tpl.php b/modules/comment/comment.tpl.php
index bb6026041c89e70ba1de9fdac93d45426da8c353..ac5f431f7dfa8bd12ada002ac7e7f21093273c52 100644
--- a/modules/comment/comment.tpl.php
+++ b/modules/comment/comment.tpl.php
@@ -23,7 +23,6 @@
  * - $status: Comment status. Possible values are:
  *   comment-unpublished, comment-published or comment-preview.
  * - $title: Linked title.
- * - $contextual_links (array): An array of contextual links for the comment.
  * - $classes: String of classes that can be used to style contextually through
  *   CSS. It can be manipulated through the variable $classes_array from
  *   preprocess functions. The default values can be one or more of the following:
@@ -35,6 +34,12 @@
  *   - comment-unpublished: An unpublished comment visible only to administrators.
  *   - comment-by-viewer: Comment by the user currently viewing the page.
  *   - comment-new: New comment since last the visit.
+ * - $title_prefix (array): An array containing additional output populated by
+ *   modules, intended to be displayed in front of the main title tag that
+ *   appears in the template.
+ * - $title_suffix (array): An array containing additional output populated by
+ *   modules, intended to be displayed after the main title tag that appears in
+ *   the template.
  *
  * These two variables are provided for context:
  * - $comment: Full comment object.
@@ -51,17 +56,15 @@
  */
 ?>
 <div class="<?php print $classes; ?> clearfix"<?php print $attributes; ?>>
-  <?php if ($contextual_links): ?>
-    <?php print render($contextual_links); ?>
-  <?php endif; ?>
-
   <?php print $picture ?>
 
   <?php if ($new): ?>
     <span class="new"><?php print $new ?></span>
   <?php endif; ?>
 
+  <?php print render($title_prefix); ?>
   <h3<?php print $title_attributes; ?>><?php print $title ?></h3>
+  <?php print render($title_suffix); ?>
 
   <div class="submitted">
     <?php
diff --git a/modules/contextual/contextual.module b/modules/contextual/contextual.module
index 080cf0d3a87a2a68f0bec92c965cc5a501c0bf40..480f9e6634d0749897428145e17fe8837c351bbf 100644
--- a/modules/contextual/contextual.module
+++ b/modules/contextual/contextual.module
@@ -64,9 +64,6 @@ function contextual_library() {
 function contextual_preprocess(&$variables, $hook) {
   static $hooks;
 
-  // Initialize the $contextual_links template variable.
-  $variables['contextual_links'] = array();
-
   // Nothing to do here if the user is not permitted to access contextual links.
   if (!user_access('access contextual links')) {
     return;
@@ -89,8 +86,8 @@ function contextual_preprocess(&$variables, $hook) {
   }
 
   if (isset($element) && is_array($element) && !empty($element['#contextual_links'])) {
-    $variables['contextual_links'] = contextual_links_view($element);
-    if (!empty($variables['contextual_links'])) {
+    $variables['title_suffix']['contextual_links'] = contextual_links_view($element);
+    if (!empty($variables['title_suffix']['contextual_links'])) {
       $variables['classes_array'][] = 'contextual-links-region';
     }
   }
diff --git a/modules/node/node.module b/modules/node/node.module
index ba298bec2d60df82f2f11b14ebca3f74d1aeb036..469565a72a4b8eb3fc8d2b70c4706ef874019060 100644
--- a/modules/node/node.module
+++ b/modules/node/node.module
@@ -1186,9 +1186,11 @@ function node_view($node, $view_mode = 'full') {
     '#node' => $node,
     '#view_mode' => $view_mode,
   );
-  // Add contextual links for this node.
+  // Add contextual links for this node except for 'full' view mode.
   // @todo Make this configurable per view mode.
-  $build['#contextual_links']['node'] = array('node', array($node->nid));
+  if ($view_mode != 'full') {
+    $build['#contextual_links']['node'] = array('node', array($node->nid));
+  }
 
   // Allow modules to modify the structured node.
   drupal_alter('node_view', $build);
diff --git a/modules/node/node.tpl.php b/modules/node/node.tpl.php
index 1cbd06a7a55b3b215450a07ad5b0f26a4bb8ba50..4c46a73c575ab94ad26030051f42f254df585018 100644
--- a/modules/node/node.tpl.php
+++ b/modules/node/node.tpl.php
@@ -18,7 +18,6 @@
  * - $node_url: Direct url of the current node.
  * - $terms: the themed list of taxonomy term links output from theme_links().
  * - $display_submitted: whether submission information should be displayed.
- * - $contextual_links (array): An array of contextual links for the node.
  * - $classes: String of classes that can be used to style contextually through
  *   CSS. It can be manipulated through the variable $classes_array from
  *   preprocess functions. The default values can be one or more of the following:
@@ -32,6 +31,12 @@
  *   - node-promoted: Nodes promoted to the front page.
  *   - node-sticky: Nodes ordered above other non-sticky nodes in teaser listings.
  *   - node-unpublished: Unpublished nodes visible only to administrators.
+ * - $title_prefix (array): An array containing additional output populated by
+ *   modules, intended to be displayed in front of the main title tag that
+ *   appears in the template.
+ * - $title_suffix (array): An array containing additional output populated by
+ *   modules, intended to be displayed after the main title tag that appears in
+ *   the template.
  *
  * Other variables:
  * - $node: Full node object. Contains data that may not be safe.
@@ -75,13 +80,11 @@
 
   <?php print $user_picture; ?>
 
-  <?php if (!$page && !empty($contextual_links)): ?>
-    <?php print render($contextual_links); ?>
-  <?php endif; ?>
-
+  <?php print render($title_prefix); ?>
   <?php if (!$page): ?>
     <h2<?php print $title_attributes; ?>><a href="<?php print $node_url; ?>"><?php print $node_title; ?></a></h2>
   <?php endif; ?>
+  <?php print render($title_suffix); ?>
 
   <?php if ($display_submitted || !empty($content['links']['terms'])): ?>
     <div class="meta">
diff --git a/modules/shortcut/shortcut.module b/modules/shortcut/shortcut.module
index a442bc00aa669f81522a61223b2a9b68ca8bf9d5..4314c9ddd1a0875ad948ac7972a5140e38705df2 100644
--- a/modules/shortcut/shortcut.module
+++ b/modules/shortcut/shortcut.module
@@ -522,9 +522,9 @@ function shortcut_renderable_links($shortcut_set = NULL) {
 }
 
 /**
- * Implements hook_page_build().
+ * Implements hook_preprocess_page().
  */
-function shortcut_page_build(&$page) {
+function shortcut_preprocess_page(&$variables) {
   if (shortcut_set_edit_access()) {
     $link = $_GET['q'];
     $query_parameters = drupal_get_query_parameters();
@@ -559,13 +559,13 @@ function shortcut_page_build(&$page) {
       $link_path = 'admin/config/system/shortcut/link/' . $mlid . '/delete';
     }
 
-    $page['add_or_remove_shortcut'] = array(
-     '#prefix' => '<div class="add-or-remove-shortcuts ' . $link_mode . '-shortcut">',
-     '#type' => 'link',
-     '#title' => '<span class="icon"></span><span class="text">' . $link_text . '</span>',
-     '#href' => $link_path,
-     '#options' => array('query' => $query, 'html' => TRUE),
-     '#suffix' => '</div>',
+    $variables['title_suffix']['add_or_remove_shortcut'] = array(
+      '#prefix' => '<div class="add-or-remove-shortcuts ' . $link_mode . '-shortcut">',
+      '#type' => 'link',
+      '#title' => '<span class="icon"></span><span class="text">' . $link_text . '</span>',
+      '#href' => $link_path,
+      '#options' => array('query' => $query, 'html' => TRUE),
+      '#suffix' => '</div>',
     );
   }
 }
@@ -609,24 +609,3 @@ function shortcut_toolbar_pre_render($toolbar) {
   return $toolbar;
 }
 
-/**
- * Implements hook_preprocess_page().
- */
-function shortcut_preprocess_page(&$variables) {
-  if (isset($variables['page']['add_or_remove_shortcut'])) {
-    $variables['add_or_remove_shortcut'] = drupal_render($variables['page']['add_or_remove_shortcut']);
-  }
-}
-
-/**
- * Implements hook_system_info_alter().
- *
- * If the overlay module is enabled, indicate that the link for adding or
- * removing shortcuts is one of the page "regions" that should display in the
- * overlay.
- */
-function shortcut_system_info_alter(&$info, $file, $type) {
-  if (module_exists('overlay') && $type == 'theme') {
-    $info['overlay_regions'][] = 'add_or_remove_shortcut';
-  }
-}
diff --git a/modules/system/page.tpl.php b/modules/system/page.tpl.php
index da52197743ed97ed38f4d23e790497e5f9f591fa..7324c7430d141b537bd6ba06271d3cebd15ab721 100644
--- a/modules/system/page.tpl.php
+++ b/modules/system/page.tpl.php
@@ -34,7 +34,13 @@
  * - $breadcrumb: The breadcrumb trail for the current page.
  *
  * Page content (in order of occurrence in the default page.tpl.php):
+ * - $title_prefix (array): An array containing additional output populated by
+ *   modules, intended to be displayed in front of the main title tag that
+ *   appears in the template.
  * - $title: The page title, for use in the actual HTML content.
+ * - $title_suffix (array): An array containing additional output populated by
+ *   modules, intended to be displayed after the main title tag that appears in
+ *   the template.
  * - $messages: HTML for status and error messages. Should be displayed
  *   prominently.
  * - $tabs (array): Tabs linking to any sub-pages beneath the current page
@@ -113,7 +119,9 @@
       <div id="content" class="column"><div class="section">
         <?php if ($page['highlight']): ?><div id="highlight"><?php print render($page['highlight']); ?></div><?php endif; ?>
         <a id="main-content"></a>
+        <?php print render($title_prefix); ?>
         <?php if ($title): ?><h1 class="title" id="page-title"><?php print $title; ?></h1><?php endif; ?>
+        <?php print render($title_suffix); ?>
         <?php if ($tabs): ?><div class="tabs"><?php print render($tabs); ?></div><?php endif; ?>
         <?php print render($page['help']); ?>
         <?php if ($action_links): ?><ul class="action-links"><?php print render($action_links); ?></ul><?php endif; ?>
diff --git a/themes/garland/block.tpl.php b/themes/garland/block.tpl.php
index da147997e45123868c38056a202ac839748e63cb..914e2703e51392fe88a973e03d66dadc5bbf1621 100644
--- a/themes/garland/block.tpl.php
+++ b/themes/garland/block.tpl.php
@@ -3,13 +3,11 @@
 ?>
 <div id="block-<?php print $block->module . '-' . $block->delta; ?>" class="<?php print $classes; ?> clearfix"<?php print $attributes; ?>>
 
-<?php if (!empty($contextual_links)): ?>
-  <?php print render($contextual_links); ?>
-<?php endif; ?>
-
+  <?php print render($title_prefix); ?>
 <?php if (!empty($block->subject)): ?>
   <h2 class="title"<?php print $title_attributes; ?>><?php print $block->subject ?></h2>
 <?php endif;?>
+  <?php print render($title_suffix); ?>
 
   <div class="content"<?php print $content_attributes; ?>><?php print $content ?></div>
 </div>
diff --git a/themes/garland/comment.tpl.php b/themes/garland/comment.tpl.php
index 2c3e1ca289659544ad2f2002bb185b9d0b3ecada..b46c1edfc31036534e5b588ff48380c4f7a2ed9e 100644
--- a/themes/garland/comment.tpl.php
+++ b/themes/garland/comment.tpl.php
@@ -5,10 +5,6 @@
 
   <div class="clearfix">
 
-  <?php if ($contextual_links): ?>
-    <?php print render($contextual_links); ?>
-  <?php endif; ?>
-
     <span class="submitted"><?php print $created; ?> — <?php print $author; ?></span>
 
   <?php if ($new) : ?>
@@ -17,7 +13,9 @@
 
   <?php print $picture ?>
 
+    <?php print render($title_prefix); ?>
     <h3<?php print $title_attributes; ?>><?php print $title ?></h3>
+    <?php print render($title_suffix); ?>
 
     <div class="content"<?php print $content_attributes; ?>>
       <?php hide($content['links']); print render($content); ?>
diff --git a/themes/garland/node.tpl.php b/themes/garland/node.tpl.php
index 4a2733f42ca96836db8646f7fb7c9e41a2d24381..3b06a2d116c4150ced72a6589f7e5920659f081b 100644
--- a/themes/garland/node.tpl.php
+++ b/themes/garland/node.tpl.php
@@ -3,15 +3,13 @@
 ?>
 <div id="node-<?php print $node->nid; ?>" class="<?php print $classes; ?>"<?php print $attributes; ?>>
 
-  <?php if (!$page && !empty($contextual_links)): ?>
-    <?php print render($contextual_links); ?>
-  <?php endif; ?>
-
   <?php print $user_picture; ?>
 
+  <?php print render($title_prefix); ?>
   <?php if (!$page): ?>
     <h2<?php print $title_attributes; ?>><a href="<?php print $node_url; ?>"><?php print $node_title; ?></a></h2>
   <?php endif; ?>
+  <?php print render($title_suffix); ?>
 
   <?php if ($display_submitted): ?>
     <span class="submitted"><?php print $date; ?> — <?php print $name; ?></span>
diff --git a/themes/garland/page.tpl.php b/themes/garland/page.tpl.php
index 11f18f6312040ca7121530ab5c54aa76c17e8f79..441a3bfe646a67eed39a432b34f25995396e0c44 100644
--- a/themes/garland/page.tpl.php
+++ b/themes/garland/page.tpl.php
@@ -42,7 +42,11 @@
           <?php if ($page['highlight']): ?><div id="highlight"><?php render($page['highlight']); ?></div><?php endif; ?>
           <a id="main-content"></a>
           <?php if ($tabs): ?><div id="tabs-wrapper" class="clearfix"><?php endif; ?>
-          <?php if ($title): ?><h1<?php print $tabs ? ' class="with-tabs"' : '' ?>><?php print $title ?></h1><?php endif; ?>
+          <?php print render($title_prefix); ?>
+          <?php if ($title): ?>
+            <h1<?php print $tabs ? ' class="with-tabs"' : '' ?>><?php print $title ?></h1>
+          <?php endif; ?>
+          <?php print render($title_suffix); ?>
           <?php if ($tabs): ?><ul class="tabs primary"><?php print render($tabs) ?></ul></div><?php endif; ?>
           <?php if ($tabs2): ?><ul class="tabs secondary"><?php print render($tabs2) ?></ul><?php endif; ?>
           <?php print $messages; ?>
diff --git a/themes/seven/page.tpl.php b/themes/seven/page.tpl.php
index 13f7b3e6d9d4c0b79e93f331d04afd52909d2d55..962bf786825d6c05a9dd287774ee53d0963436d3 100644
--- a/themes/seven/page.tpl.php
+++ b/themes/seven/page.tpl.php
@@ -4,8 +4,11 @@
   <div class="element-invisible"><a id="main-content"></a></div>
   <div id="branding" class="clearfix">
     <?php print $breadcrumb; ?>
-    <?php if ($title): ?><h1 class="page-title"><?php print $title; ?></h1><?php endif; ?>
-    <?php if (isset($add_or_remove_shortcut)): ?><?php print $add_or_remove_shortcut; ?><?php endif; ?>
+    <?php print render($title_prefix); ?>
+    <?php if ($title): ?>
+      <h1 class="page-title"><?php print $title; ?></h1>
+    <?php endif; ?>
+    <?php print render($title_suffix); ?>
     <?php if ($primary_local_tasks): ?><ul class="tabs primary"><?php print render($primary_local_tasks); ?></ul><?php endif; ?>
   </div>