diff --git a/includes/content.inc b/includes/content.inc
index 823c2f88d0385785e6085d084d00ab59d7c57b66..0f2d85e1ab9f76b20bc6d25632bb1f788316ca1c 100644
--- a/includes/content.inc
+++ b/includes/content.inc
@@ -220,6 +220,8 @@ function ctools_content_prepare_subtype(&$subtype, $plugin) {
  *   The name of the subtype being rendered.
  * @param $conf
  *   The configuration for the content type.
+ * @param $keywords
+ *   An array of replacement keywords that come from outside contexts.
  * @param $args
  *   The arguments provided to the owner of the content type. Some content may
  *   wish to configure itself based on the arguments the panel or dashboard
@@ -280,8 +282,8 @@ function ctools_content_render($type, $subtype, $conf, $keywords = array(), $arg
 
     if (!empty($content->title)) {
       // Perform substitutions
-      if (!empty($keywords)) {
-        $content->title = strtr($content->title, $keywords);
+      if (!empty($keywords) || !empty($contexts)) {
+        $content->title = ctools_context_keyword_substitute($content->title, $keywords, $context);
       }
 
       // Sterilize the title
diff --git a/includes/context-admin.inc b/includes/context-admin.inc
index 928986daf535cfa84471a59c4dac7470f77b9c88..6f575d679b69e7c17223d853ce0c65a9df3d77ea 100644
--- a/includes/context-admin.inc
+++ b/includes/context-admin.inc
@@ -790,7 +790,7 @@ function ctools_edit_argument_form(&$form_state) {
     '#type' => 'textfield',
     '#title' => t('Title'),
     '#default_value' => $arg['title'],
-    '#description' => t('Enter a title to use when this argument is present. You may use %KEYWORD substitution, where the keyword is specified by the administrator.'),
+    '#description' => t('Enter a title to use when this argument is present. You may use %KEYWORD substitution, where the keyword is specified below.'),
   );
 
   $form['argument']['identifier'] = array(
diff --git a/includes/context.inc b/includes/context.inc
index a8cca3577e30b9fff555c6b83f0313a9d0ca7fca..ac0a3de1f250607fadee85c185ce696f828105ff 100644
--- a/includes/context.inc
+++ b/includes/context.inc
@@ -335,7 +335,7 @@ function _ctools_context_converter_selector($contexts, $required, $default, $num
         continue;
       }
       $key = $context->get_identifier();
-      if ($converters = ctools_context_get_converters($cid, $context)) {
+      if ($converters = ctools_context_get_converters($cid . '.', $context)) {
         $options[$key] = $converters;
       }
     }
@@ -367,7 +367,7 @@ function _ctools_context_converter_selector($contexts, $required, $default, $num
  */
 function ctools_context_get_converters($cid, $context) {
   if (empty($context->plugin)) {
-    return;
+    return array();
   }
 
   return _ctools_context_get_converters($cid, $context->plugin);
@@ -379,7 +379,7 @@ function ctools_context_get_converters($cid, $context) {
 function _ctools_context_get_converters($id, $plugin_name) {
   $plugin = ctools_get_context($plugin_name);
   if (empty($plugin['convert list'])) {
-    return;
+    return array();
   }
 
   $converters = array();
@@ -398,7 +398,7 @@ function _ctools_context_get_converters($id, $plugin_name) {
   // Now, change them all to include the plugin:
   $return = array();
   foreach ($converters as $key => $title) {
-    $return[$id . '.' . $key] = $title;
+    $return[$id . $key] = $title;
   }
 
   natcasesort($return);
@@ -412,7 +412,7 @@ function ctools_context_get_all_converters() {
   $contexts = ctools_get_contexts();
   $converters = array();
   foreach ($contexts as $name => $context) {
-    $context_converters = _ctools_context_get_converters($name, $name);
+    $context_converters = _ctools_context_get_converters($name . '.', $name);
     if ($context_converters) {
       $converters[$context['title']] = $context_converters;
     }
@@ -514,24 +514,44 @@ function ctools_context_create_empty($type) {
 }
 
 /**
- * Fetch keywords for use in string substitutions.
- *
- * @param $contexts
- *   An array of contexts.
- *
- * @return
- *   An array of keyword substitutions suitable for @code{strtr()}
+ * Perform keyword and context substitutions.
  */
-function ctools_context_get_keywords($contexts) {
-  $keywords = array();
-  if (!empty($contexts)) {
-    foreach ($contexts as $id => $context) {
-      if ($keyword = $context->get_keyword()) {
-        $keywords["%$keyword"] = $context->get_title();
+function ctools_context_keyword_substitute($string, $keywords, $contexts) {
+  // Ensure a default keyword exists:
+  $keywords['%%'] = '%';
+
+  // Match contexts to the base keywords:
+  $context_keywords = array();
+  foreach ($contexts as $context) {
+    if (isset($context->keyword)) {
+      $context_keywords[$context->keyword] = $context;
+    }
+  }
+
+  // Look for context matches we we only have to convert known matches.
+  $matches = array();
+  if (preg_match_all('/%([a-zA-Z%:]+)/us', $string, $matches)) {
+    foreach ($matches[1] as $keyword) {
+      // Ignore anything it finds with %%.
+      if ($keyword[0] == '%') {
+        continue;
+      }
+
+      if (strpos($keyword, ':')) {
+        list($context, $converter) = explode(':', $keyword);
+        if (isset($context_keywords[$context])) {
+          $keywords['%' . $keyword] = ctools_context_convert_context($context_keywords[$context], $converter);
+        }
+      }
+      else {
+        if (isset($context_keywords[$keyword])) {
+          $keywords['%' . $keyword] = $context_keywords[$keyword]->title;
+        }
       }
     }
   }
-  return $keywords;
+
+  return strtr($string, $keywords);
 }
 
 /**
diff --git a/includes/context.theme.inc b/includes/context.theme.inc
index 25c194a8500e482c406f8f2aa10f7436d64df390..f05e005a3918d30cf6f210e64eeb315056935ab0 100644
--- a/includes/context.theme.inc
+++ b/includes/context.theme.inc
@@ -122,6 +122,8 @@ function theme_ctools_context_list($object, $header = '') {
   $output = '';
   $count  = 1;
 
+  $contexts = ctools_context_load_contexts($object);
+
   // Describe 'built in' contexts.
   if (!empty($object->base_contexts)) {
     foreach ($object->base_contexts as $id => $context) {
@@ -129,7 +131,12 @@ function theme_ctools_context_list($object, $header = '') {
       $output .= '<td valign="top"><em>' . t('Built in context') . '</em></td>';
       $desc = check_plain($context->identifier);
       if (isset($context->keyword)) {
-        $desc .= '<div class="description">' . t('Keyword: %@keyword', array('@keyword' => $context->keyword)) . '</div>';
+        $desc .= '<div class="description">' . t('Keyword: %@keyword', array('@keyword' => $context->keyword));
+        foreach (ctools_context_get_converters('%' . $context->keyword . ':', $context) as $keyword => $title) {
+          $desc .= '<br/>' . t('@keyword --&gt; @title', array('@context' => $keyword, '@title' => $title));
+        }
+        $desc .= '</div>';
+
       }
       if (isset($context->description)) {
         $desc .= '<div class="description">' . filter_xss_admin($context->description) . '</div>';
@@ -148,7 +155,11 @@ function theme_ctools_context_list($object, $header = '') {
       $output .= '<td valign="top"><em>' . t('Argument @count', array('@count' => $count)) . '</em></td>';
       $desc = check_plain($argument['identifier']);
       if (isset($argument['keyword'])) {
-        $desc .= '<div class="description">' . t('Keyword: %@keyword', array('@keyword' => $argument['keyword'])) . '</div>';
+        $desc .= '<div class="description">' . t('Keyword: %@keyword', array('@keyword' => $argument['keyword']));
+        foreach (ctools_context_get_converters('%' . $argument['keyword'] . ':', $contexts[ctools_context_id($argument, 'argument')]) as $keyword => $title) {
+          $desc .= '<br/>' . t('@keyword --&gt; @title', array('@keyword' => $keyword, '@title' => $title));
+        }
+        $desc .= '</div>';
       }
       $output .= '<td>' . $desc . '</td>';
       $output .= '</tr>';
@@ -165,7 +176,11 @@ function theme_ctools_context_list($object, $header = '') {
       $output .= '<td valign="top"><em>' . t('Context @count', array('@count' => $count)) . '</em></td>';
       $desc = check_plain($context['identifier']);
       if (isset($context['keyword'])) {
-        $desc .= '<div class="description">' . t('Keyword: %@keyword', array('@keyword' => $context['keyword'])) . '</div>';
+        $desc .= '<div class="description">' . t('Keyword: %@keyword', array('@keyword' => $context['keyword']));
+        foreach (ctools_context_get_converters('%' . $context['keyword'] . ':', $contexts[ctools_context_id($context, 'context')]) as $keyword => $title) {
+          $desc .= '<br/>' . t('@keyword --&gt; @title', array('@keyword' => $keyword, '@title' => $title));
+        }
+        $desc .= '</div>';
       }
       $output .= '<td>' . $desc . '</td>';
       $output .= '</tr>';
@@ -181,7 +196,11 @@ function theme_ctools_context_list($object, $header = '') {
       $output .= '<td valign="top"><em>' . t('From "@title"', array('@title' => $titles[$relationship['context']])) . '</em></td>';
       $desc = check_plain($relationship['identifier']);
       if (isset($relationship['keyword'])) {
-        $desc .= '<div class="description">' . t('Keyword: %@keyword', array('@keyword' => $relationship['keyword'])) . '</div>';
+        $desc .= '<div class="description">' . t('Keyword: %@keyword', array('@keyword' => $relationship['keyword']));
+        foreach (ctools_context_get_converters('%' . $relationship['keyword'] . ':', $contexts[ctools_context_id($relationship, 'relationship')]) as $keyword => $title) {
+          $desc .= '<br/>' . t('@keyword --&gt; @title', array('@keyword' => $keyword, '@title' => $title));
+        }
+        $desc .= '</div>';
       }
       $output .= '<td>' . $desc . '</td>';
       $output .= '</tr>';
diff --git a/plugins/content_types/node_context/node_content.inc b/plugins/content_types/node_context/node_content.inc
index a394de5a16012ddc37190c9c7b8d89d62f03b2eb..bab9c660aa0617750fbba6188068b4c26e34cc6b 100644
--- a/plugins/content_types/node_context/node_content.inc
+++ b/plugins/content_types/node_context/node_content.inc
@@ -122,6 +122,8 @@ function ctools_node_content_render_node($node, $conf) {
  * Returns an edit form for the custom type.
  */
 function ctools_node_content_content_type_edit_form(&$form, &$form_state) {
+  $conf = $form_state['conf'];
+
   $form['link'] = array(
     '#title' => t('Link title to node'),
     '#type' => 'checkbox',
@@ -163,7 +165,7 @@ function ctools_node_content_content_type_edit_form(&$form, &$form_state) {
 
   $form['leave_node_title'] = array(
     '#type' => 'checkbox',
-    '#default_value' => $conf['leave_node_title'],
+    '#default_value' => !empty($conf['leave_node_title']),
     '#title' => t('Leave node title'),
     '#description' => t('Advanced: if checked, do not touch the node title; this can cause the node title to appear twice unless your theme is aware of this.'),
   );
diff --git a/plugins/contexts/term.inc b/plugins/contexts/term.inc
index dd1c6994fd17262a786ffa1e1b52f2c235988817..82f11f3a7a6529881d22b4aadc6b3a922dd269c2 100644
--- a/plugins/contexts/term.inc
+++ b/plugins/contexts/term.inc
@@ -21,7 +21,7 @@ function ctools_term_ctools_contexts() {
     'no ui' => TRUE,
     'context name' => 'term',
     'convert list' => array(
-      'id' => t('Term ID'),
+      'tid' => t('Term ID'),
       'name' => t('Term name'),
       'vid' => t('Vocabulary ID'),
     ),
diff --git a/plugins/contexts/user.inc b/plugins/contexts/user.inc
index 7a06f19cb9a5690ae89c5d4a02be1633d28f04d9..33e48cf6235d45515c0d8248c9ae7cd9a224f083 100644
--- a/plugins/contexts/user.inc
+++ b/plugins/contexts/user.inc
@@ -20,6 +20,11 @@ function ctools_user_ctools_contexts() {
     'keyword' => 'user',
     'no ui' => TRUE,
     'context name' => 'user',
+    'convert list' => array(
+      'uid' => t('User ID'),
+      'name' => t('User name'),
+    ),
+    'convert' => 'ctools_context_user_convert',
   );
   return $args;
 }
@@ -53,3 +58,14 @@ function ctools_context_user_settings_form($conf, $external = FALSE) {
   return $form;
 }
 
+/**
+ * Convert a context into a string.
+ */
+function ctools_context_user_convert($context, $type) {
+  switch ($type) {
+    case 'uid':
+      return $context->data->uid;
+    case 'name':
+      return $context->data->name;
+  }
+}
diff --git a/views_content/plugins/content_types/views.inc b/views_content/plugins/content_types/views.inc
index cda845bc54284ac97bc9cce431404c9d1a0f42ea..33dbb7b8ef65344de6e1e3ecb7d1c61c20b50705 100644
--- a/views_content/plugins/content_types/views.inc
+++ b/views_content/plugins/content_types/views.inc
@@ -434,7 +434,7 @@ function views_content_views_content_type_admin_info($subtype, $conf, $contexts)
       }
 
       if (!empty($contexts[$cid])) {
-        $converters = ctools_context_get_converters($cid, $contexts[$cid]);
+        $converters = ctools_context_get_converters($cid . '.', $contexts[$cid]);
         $converter = !empty($converters[$context_info]) ? $converters[$context_info] : t('Default');
         $block->content .= '<li>' . t('Argument @arg using context @context converted into @converter', array(
           '@arg' => $argument->ui_name(), '@context' => $contexts[$cid]->get_identifier(),