diff --git a/core/modules/node/content_types.inc b/core/modules/node/content_types.inc
index c76a5e2..40ae861 100644
--- a/core/modules/node/content_types.inc
+++ b/core/modules/node/content_types.inc
@@ -200,6 +200,25 @@ function node_type_form($form, &$form_state, $type = NULL) {
     '#default_value' => variable_get('node_submitted_' . $type->type, TRUE),
     '#description' => t('Author username and publish date will be displayed.'),
   );
+  $form['lists'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Recent posts'),
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+    '#group' => 'additional_settings',
+  );
+  $form['lists']['node_list_page'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Provide a page of recent posts'),
+    '#default_value' => variable_get('node_list_page_' . $type->type, FALSE),
+    '#description' => t('Create a dedicated page and RSS feed listing recent posts of this content type.'),
+  );
+  $form['lists']['node_list_block'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Provide a sidebar block of recent posts'),
+    '#default_value' => variable_get('node_list_block_' . $type->type, FALSE),
+    '#description' => t('Create a sidebar block listing recent posts of this content type.'),
+  );
   $form['old_type'] = array(
     '#type' => 'value',
     '#value' => $type->type,
@@ -361,6 +380,14 @@ function node_type_form_submit($form, &$form_state) {
     watchdog('node', 'Added content type %name.', $t_args, WATCHDOG_NOTICE, l(t('view'), 'admin/structure/types'));
   }
 
+  if ($variables['node_list_block'] && !$form['lists']['node_list_block']['#default_value']) {
+    drupal_set_message(t('A block listing recent %name posts has been created, and can be configured on the !link.', array('%name' => $type->name, '!link' => l(t('block administration page'), 'admin/structure/block'))));
+  }
+  if ($variables['node_list_page'] && !$form['lists']['node_list_page']['#default_value']) {
+    $type_url_str = str_replace('_', '-', $type->type);
+    drupal_set_message(t('A page listing recent %name posts has been created, and can be viewed at !link.', array('%name' => $type->name, '!link' => l("content/$type_url_str", "content/$type_url_str"))));
+  }
+
   $form_state['redirect'] = 'admin/structure/types';
   return;
 }
diff --git a/core/modules/node/content_types.js b/core/modules/node/content_types.js
index 0031c32..502a504 100644
--- a/core/modules/node/content_types.js
+++ b/core/modules/node/content_types.js
@@ -28,6 +28,21 @@ Drupal.behaviors.contentTypes = {
       }
       return vals.join(', ');
     });
+    $('fieldset#edit-lists', context).drupalSetSummary(function(context) {
+      var vals = [];
+      if ($('#edit-node-list-block', context).is(':checked')) {
+        vals.unshift(Drupal.t('recent posts block'));
+      }
+      if ($('#edit-node-list-page', context).is(':checked')) {
+        vals.unshift(Drupal.t('recent posts page'));
+      }
+      if (vals.length == 0) {
+        return Drupal.t("Don't list recent posts");
+      }
+      else {
+        return Drupal.t('Generate') + ' ' + vals.join(', ');
+      }
+    });
   }
 };
 
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index 93f0ddc..333eb5d 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -1958,8 +1958,13 @@ function _node_revision_access($node, $op = 'view') {
  *
  * @see node_menu()
  */
-function _node_add_access() {
-  $types = node_type_get_types();
+function _node_add_access($type = NULL) {
+   if (empty($type)) {
+     $types = node_type_get_types();
+   }
+   else {
+     $types = array($type);
+  }
   foreach ($types as $type) {
     if (node_hook($type->type, 'form') && node_access('create', $type->type)) {
       return TRUE;
@@ -2152,6 +2157,22 @@ function node_menu() {
     'access arguments' => array(1, 'delete'),
     'file' => 'node.pages.inc',
   );
+
+  $items['content/%node_type'] = array(
+    'title callback' => 'node_type_page_title',
+    'title arguments' => array(1),
+    'page callback' => 'node_page_type',
+    'page arguments' => array(1),
+    'access arguments' => array('access content'),
+  );
+  $items['content/%node_type/rss.xml'] = array(
+    'title callback' => 'node_type_page_title',
+    'title arguments' => array(1),
+    'page callback' => 'node_type_feed',
+    'page arguments' => array(1),
+    'access arguments' => array('access content'),
+    'type' => MENU_CALLBACK,
+  );
   return $items;
 }
 
@@ -2236,6 +2257,13 @@ function node_block_info() {
   $blocks['recent']['info'] = t('Recent content');
   $blocks['recent']['properties']['administrative'] = TRUE;
 
+  foreach (node_type_get_types() as $type) {
+    if (variable_get('node_list_block_' . $type->type, FALSE)) {
+      $blocks["recent_$type->type"]['info'] = t('Recent @name content', array('@name' => $type->name));
+      $blocks["recent_$type->type"]['cache'] = DRUPAL_CACHE_PER_USER;
+    }
+  }
+
   return $blocks;
 }
 
@@ -2268,6 +2296,52 @@ function node_block_view($delta = '') {
         }
       }
       break;
+
+    default:
+      if (substr_count($delta, 'recent_')) {
+        $delta_type = str_replace('recent_', '', $delta);
+        if (user_access('access content') && variable_get("node_list_block_$delta_type", FALSE)) {
+          $types = node_type_get_types();
+          if (isset($types[$delta_type])) {
+            $type = $types[$delta_type];
+            $select = db_select('node', 'n')
+              ->fields('n', array('nid', 'sticky', 'created'))
+              ->condition('type', $type->type)
+              ->condition('status', 1)
+              ->orderBy('sticky', 'DESC')
+              ->orderBy('created', 'DESC')
+              ->range(0, variable_get('default_nodes_main', 10))
+              ->addTag('node_access');
+
+            $nids = $select->execute()->fetchCol();
+
+            if ($nids) {
+              $nodes = node_load_multiple($nids);
+              $block['subject'] = t('Recent @name content', array('@name' => $type->name));
+
+              // TODO: Make this themable?
+              $block['content']['list'] = array(
+                '#theme' => 'links__node_type_block',
+              );
+              foreach ($nodes as $node) {
+                $block['content']['list']['#links']["node-$node->nid"] = array(
+                  'title' => $node->title,
+                  'href' => 'node/' . $node->nid,
+                );
+              }
+
+              if (variable_get("node_list_page_$type->type", FALSE)) {
+                $type_url_str = str_replace('_', '-', $type->type);
+                $block['content']['more_link'] = array(
+                  '#theme' => 'more_link',
+                  '#title' => t('Read more'),
+                  '#url' => "content/$type_url_str",
+                );
+              }
+            }
+          }
+        }
+      }
   }
   return $block;
 }
@@ -2642,6 +2716,34 @@ function node_feed($nids = FALSE, $channel = array()) {
   print $output;
 }
 
+ /**
+  * Construct a type-limited RSS feed.
+  *
+  * @param $type
+  *   A node type object.
+  */
+function node_type_feed($type) {
+  global $base_url;
+  $nids = db_select('node', 'n')
+    ->fields('n', array('nid', 'created'))
+    ->condition('n.type', $type->type)
+    ->condition('status', 1)
+    ->orderBy('n.created', 'DESC')
+    ->range(0, variable_get('feed_default_items', 10))
+    ->addTag('node_access')
+    ->execute()
+    ->fetchCol();
+
+  $type_url_str = str_replace('_', '-', $type->type);
+
+  $channel = array(
+    'link' => "$base_url/content/$type_url_str",
+    'title' => t('%site recent %name content', array('%site' => variable_get('site_name', 'Drupal'), '%name' => $type->name)),
+  );
+
+  node_feed($nids, $channel);
+}
+
 /**
  * Constructs a drupal_render() style array from an array of loaded nodes.
  *
@@ -2696,7 +2798,7 @@ function node_page_default() {
     $build = node_view_multiple($nodes);
 
     // 'rss.xml' is a path, not a file, registered in node_menu().
-    drupal_add_feed('rss.xml', variable_get('site_name', 'Drupal') . ' ' . t('RSS'));
+    $build['#attached']['drupal_add_feed'][] = array('rss.xml', variable_get('site_name', 'Drupal') . ' ' . t('RSS'));
     $build['pager'] = array(
       '#theme' => 'pager',
       '#weight' => 5,
@@ -2725,6 +2827,65 @@ function node_page_default() {
   return $build;
 }
 
+ /**
+ * Page callback: Displays a list of nodes of single type.
+ *
+ * Path: content/%node_type
+ *
+ * @param $type
+ *   The node type.
+ *
+ * @see node_menu()
+  */
+function node_page_type($type) {
+  if (!variable_get("node_list_page_$type->type", FALSE)) {
+    return MENU_NOT_FOUND;
+  }
+
+  drupal_set_title(t('Recent @type content', array('@type' => node_type_get_name($type))));
+
+  $select = db_select('node', 'n')
+    ->fields('n', array('nid', 'sticky', 'created'))
+    ->condition('status', 1)
+    ->condition('type', $type->type)
+    ->orderBy('sticky', 'DESC')
+    ->orderBy('created', 'DESC')
+    ->extend('PagerDefault')
+    ->limit(variable_get('default_nodes_main', 10))
+    ->addTag('node_access');
+
+  $nids = $select->execute()->fetchCol();
+
+  $type_url_str = str_replace('_', '-', $type->type);
+
+  $build = array();
+  if (empty($nids)) {
+    $build['empty_message'] = array(
+      '#markup' => '<p>' . t('No %type content has been created yet.', array('%type' => $type->name)) . '</p>',
+    );
+    if (_node_add_access($type)) {
+      $build['create_link'] = array(
+        '#theme' => 'item_list',
+        '#items' => array(l(t('Add new content'), "node/add/$type_url_str")),
+      );
+    }
+  }
+  else {
+    $nodes = node_load_multiple($nids);
+    $build = node_view_multiple($nodes);
+    $build['#attached']['drupal_add_feed'][] = array(
+      "content/$type_url_str/rss.xml",
+      variable_get('site_name', 'Drupal') . ' ' . check_plain($type->name) . ' ' . t('RSS'),
+    );
+
+    $build['pager'] = array(
+      '#theme' => 'pager',
+      '#weight' => 5,
+    );
+  }
+  return $build;
+}
+
 /**
  * Page callback: Displays a single node.
  *
