diff --git js/skinr_ui.rules.js js/skinr_ui.rules.js
new file mode 100644
index 0000000..608257b
--- /dev/null
+++ js/skinr_ui.rules.js
@@ -0,0 +1,59 @@
+// $Id$
+(function ($) {
+
+/**
+ * Provide the summary information for the block settings vertical tabs.
+ */
+Drupal.behaviors.skinrUIRuleSettingsSummary = {
+  attach: function (context) {
+    // The drupalSetSummary method required for this behavior is not available
+    // on the Blocks administration page, so we need to make sure this
+    // behavior is processed only if drupalSetSummary is defined.
+    if (typeof jQuery.fn.drupalSetSummary == 'undefined') {
+      return;
+    }
+
+    $('fieldset#edit-path', context).drupalSetSummary(function (context) {
+      if (!$('textarea[name="pages"]', context).val()) {
+        return Drupal.t('Not restricted');
+      }
+      else {
+        return Drupal.t('Restricted to certain pages');
+      }
+    });
+
+    $('fieldset#edit-node-type', context).drupalSetSummary(function (context) {
+      var vals = [];
+      $('input[type="checkbox"]:checked', context).each(function () {
+        vals.push($.trim($(this).next('label').text()));
+      });
+      if (!vals.length) {
+        vals.push(Drupal.t('Not restricted'));
+      }
+      return vals.join(', ');
+    });
+
+    $('fieldset#edit-role', context).drupalSetSummary(function (context) {
+      var vals = [];
+      $('input[type="checkbox"]:checked', context).each(function () {
+        vals.push($.trim($(this).next('label').text()));
+      });
+      if (!vals.length) {
+        vals.push(Drupal.t('Not restricted'));
+      }
+      return vals.join(', ');
+    });
+
+    $('fieldset#edit-user', context).drupalSetSummary(function (context) {
+      var $radio = $('input[name="custom"]:checked', context);
+      if ($radio.val() == 0) {
+        return Drupal.t('Not customizable');
+      }
+      else {
+        return $radio.next('label').text();
+      }
+    });
+  }
+};
+
+})(jQuery);
diff --git skinr.install skinr.install
index 34994ef..265f4d6 100644
--- skinr.install
+++ skinr.install
@@ -79,6 +79,13 @@ function skinr_schema() {
         'not null' => TRUE,
         'default' => '',
       ),
+      'node_types' => array(
+        'type' => 'text',
+        'size' => 'normal',
+        'not null' => FALSE,
+        'serialize' => TRUE,
+        'description' => 'A serialized array of node types for this record.',
+      ),
       'roles' => array(
         'type' => 'text',
         'size' => 'normal',
@@ -91,12 +98,12 @@ function skinr_schema() {
         'not null' => TRUE,
         'default' => 0,
         'size' => 'tiny',
-        'description' => 'Flag to indicate how to show on pages. (0 = Show on all pages except listed pages, 1 = Show only on listed pages, 2 = Use custom PHP code to determine visibility.)',
+        'description' => 'Flag to indicate how to show blocks on pages. (0 = Show on all pages except listed pages, 1 = Show only on listed pages, 2 = Use custom PHP code to determine visibility)',
       ),
       'pages' => array(
         'type' => 'text',
         'not null' => TRUE,
-        'description' => 'Contents of the "Pages" block; contains either a list of paths on which to include/exclude the region or PHP code, depending on the visibility setting.',
+        'description' => 'Contents of the "Pages" block; contains either a list of paths on which to include/exclude the block or PHP code, depending on "visibility" setting.',
       ),
     ),
     'primary key' => array('rid'),
diff --git skinr.module skinr.module
index f1b5263..8ffab9e 100644
--- skinr.module
+++ skinr.module
@@ -12,6 +12,21 @@
 define('SKINR_VERSION', 2);
 
 /**
+ * Show this rule on every page except the listed pages.
+ */
+define('SKINR_RULE_VISIBILITY_NOTLISTED', 0);
+
+/**
+ * Show this rule on only the listed pages.
+ */
+define('SKINR_RULE_VISIBILITY_LISTED', 1);
+
+/**
+ * Show this rule if the associated PHP code returns TRUE.
+ */
+define('SKINR_RULE_VISIBILITY_PHP', 2);
+
+/**
  * Implements hook_help().
  */
 function skinr_help($path, $arg) {
@@ -378,6 +393,7 @@ function skinr_rule_load_multiple($rids = array(), $conditions = array()) {
     $select->condition($field, $condition);
   }
   foreach ($select->execute() as $rule) {
+    $rule->node_types = unserialize($rule->node_types);
     $rule->roles = unserialize($rule->roles);
     $rules[$rule->rid] = $rule;
   }
@@ -407,40 +423,76 @@ function skinr_rule_delete($rid) {
  *
  * @param $rid
  *   The rule ID.
- *
- * @todo Rename this function to skinr_rule_is_visible().
  */
-function skinr_rule_visible($rid) {
+function skinr_rule_is_visible($rid) {
   global $user;
 
   if ($rule = skinr_rule_load($rid)) {
-    $page_match = TRUE;
-
-    if (!empty($record['roles']) && ($user->uid != 1) && !count(array_intersect(array_keys($user->roles), $rule->roles))) {
+    // Check role visibility.
+    if (!empty($rule->roles) && ($user->uid != 1) && !count(array_intersect(array_keys($user->roles), $node_types))) {
       return FALSE;
     }
+ 
+    // Check content type visibility.
+    // If a rule has no node types associated, it is displayed for every type.
+    // For rules with node types associated, if the node type does not match
+    // the settings from this rule, return FALSE.
+    if (!empty($rule->node_types)) {
+      $node = menu_get_object();
+      $node_types = node_type_get_types();
+      if (arg(0) == 'node' && arg(1) == 'add' && arg(2)) {
+        $node_add_arg = strtr(arg(2), '-', '_');
+      }
+
+      if (!empty($node)) {
+        // This is a node or node edit page.
+        if (!isset($rule->node_types[$node->type])) {
+          // This rule should not be displayed for this node type.
+          return FALSE;
+        }
+      }
+      elseif (isset($node_add_arg) && isset($node_types[$node_add_arg])) {
+        // This is a node creation page.
+        if (!isset($rule->node_types[$node_add_arg])) {
+          // This rule should not be displayed for this node type.
+          return FALSE;
+        }
+      }
+      else {
+        // This is not a node page, remove the rule.
+        return FALSE;
+      }
+    }
 
-    // Match path if necessary
+    // Match path if necessary.
     if ($rule->pages) {
-      if ($rule->visibility < 2) {
-        $path = drupal_get_path_alias($_GET['q']);
-        // Compare with the internal and path alias (if any).
-        $page_match = drupal_match_path($path, $rule->pages);
+      // Convert path to lowercase. This allows comparison of the same path
+      // with different case. Ex: /Page, /page, /PAGE.
+      $pages = drupal_strtolower($rule->pages);
+      if ($rule->visibility < SKINR_RULE_VISIBILITY_PHP) {
+        // Convert the Drupal path to lowercase
+        $path = drupal_strtolower(drupal_get_path_alias($_GET['q']));
+        // Compare the lowercase internal and lowercase path alias (if any).
+        $page_match = drupal_match_path($path, $pages);
         if ($path != $_GET['q']) {
-          $page_match = $page_match || drupal_match_path($_GET['q'], $rule->pages);
+          $page_match = $page_match || drupal_match_path($_GET['q'], $pages);
         }
-        // When $rule->visibility has a value of 0, the item is displayed on
-        // all pages except those listed in $rule->pages. When set to 1, it
-        // is displayed only on those pages listed in $rule->pages.
+        // When $rule->visibility has a value of 0 (SKINR_RULE_VISIBILITY_NOTLISTED),
+        // the rule is displayed on all pages except those listed in $rule->pages.
+        // When set to 1 (SKINR_RULE_VISIBILITY_LISTED), it is displayed only on those
+        // pages listed in $rule->pages.
         $page_match = !($rule->visibility xor $page_match);
       }
+      elseif (module_exists('php')) {
+        $page_match = php_eval($rule->pages);
+      }
       else {
-        // PHP.
-        if (module_exists('php')) {
-          $page_match = php_eval($rule->pages);
-        }
+        $page_match = FALSE;
       }
     }
+    else {
+      $page_match = TRUE;
+    }
     return $page_match;
   }
   return FALSE;
diff --git skinr.skinr.inc skinr.skinr.inc
index bf8fda3..fdf048b 100644
--- skinr.skinr.inc
+++ skinr.skinr.inc
@@ -148,7 +148,7 @@ function rules_skinr_preprocess_index_handler(&$variables) {
   // Find any page level skinr options and return an array of them.
   $indices = array();
   foreach ($rules as $rule) {
-    if (skinr_rule_visible($rule->rid)) {
+    if (skinr_rule_is_visible($rule->rid)) {
       $indices[] = $rule->rid;
     }
   }
@@ -186,7 +186,7 @@ function rules_skinr_contextual_links(&$variables) {
   $counter = 1;
 
   foreach ($rules as $rule) {
-    if (skinr_rule_visible($rule->rid)) {
+    if (skinr_rule_is_visible($rule->rid)) {
       $links['skinr-rule-' . $counter++] = array(
         'admin/config/skinr/edit/nojs', array('page', $rule->rid),
       );
diff --git skinr_ui.rules.inc skinr_ui.rules.inc
index fb91ce4..5198034 100644
--- skinr_ui.rules.inc
+++ skinr_ui.rules.inc
@@ -119,18 +119,16 @@ function skinr_rule_add_submit($form, &$form_state) {
 }
 
 /**
- * Menu callback; displays the edit form for a skinr rule.
+ * Form builder for the rule configuration form.
  *
  * @param $rid
  *   The rule ID.
  *
+ * @see skinr_rule_edit_submit()
  * @ingroup forms
  */
 function skinr_rule_edit($form, &$form_state, $rid = NULL) {
   $form['rule'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Skinr rule visibility'),
-    '#collapsible' => TRUE,
     '#weight' => -1,
   );
 
@@ -138,6 +136,7 @@ function skinr_rule_edit($form, &$form_state, $rid = NULL) {
     $rule = array(
       'title' => $form_state['values']['title'],
       'rule_type' => $form_state['values']['rule_type'],
+      'node_types' => $form_state['values']['types'],
       'roles' => $form_state['values']['roles'],
       'visibility' => $form_state['values']['visibility'],
       'pages' => $form_state['values']['pages'],
@@ -154,6 +153,7 @@ function skinr_rule_edit($form, &$form_state, $rid = NULL) {
     $rule = array(
       'title' => '',
       'rule_type' => '',
+      'node_types' => array(),
       'roles' => array(),
       'visibility' => 0,
       'pages' => '',
@@ -162,7 +162,7 @@ function skinr_rule_edit($form, &$form_state, $rid = NULL) {
 
   $form['rule']['title'] = array(
     '#type' => 'textfield',
-    '#title' => t('Title'),
+    '#title' => t('Rule title'),
     '#default_value' => $rule['title'],
     '#description' => t('Descriptive title for this rule; used by administrators.'),
     '#required' => TRUE,
@@ -174,49 +174,115 @@ function skinr_rule_edit($form, &$form_state, $rid = NULL) {
   );
   $form['rule']['rule_type_displayed'] = array(
     '#type' => 'item',
-    '#title' => t('Type'),
+    '#title' => t('Rule type'),
     '#markup' => $rule['rule_type'],
     '#description' => t('Type of element the rule is applied to.'),
   );
 
-  // Inject the rule's form elements here.
-  $form['rule']['roles'] = array(
-    '#type' => 'checkboxes',
-    '#title' => t('Show for specific roles'),
-    '#default_value' => $rule['roles'],
-    '#options' => user_roles(),
-    '#description' => t('Show only for the selected role(s). If you select no roles, it will be visible to all users.'),
+  // Visibility settings.
+  $form['visibility_title'] = array(
+    '#type' => 'item',
+    '#title' => t('Visibility settings'),
+  );
+  $form['visibility'] = array(
+    '#type' => 'vertical_tabs',
+    '#attached' => array(
+      'js' => array(drupal_get_path('module', 'skinr_ui') . '/js/skinr_ui.rules.js'),
+    ),
   );
 
-  // Set up options and description.
-  $options = array(0 => t('Show on every page except the listed pages.'), 1 => t('Show on only the listed pages.'));
-  $description = t("Enter one page per line as Drupal paths. The '*' character is a wildcard. Example paths are %blog for the blog page and %blog-wildcard for every personal blog. %front is the front page.", array('%blog' => 'blog', '%blog-wildcard' => 'blog/*', '%front' => '<front>'));
+  // Per-path visibility.
+  $form['visibility']['path'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Pages'),
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+    '#group' => 'visibility',
+    '#weight' => 0,
+  );
 
-  // Add the PHP specific stuff, if user has access.
-  if (module_exists('php') && user_access('use PHP for visibility')) {
-    $options[2] = t('Show if the following PHP code returns <code>TRUE</code> (PHP-mode, experts only).');
-    $description .= ' '. t('If the PHP-mode is chosen, enter PHP code between %php. Note that executing incorrect PHP-code can break your Drupal site.', array('%php' => '<?php ?>'));
+  $access = user_access('use PHP for settings');
+  if (isset($rule['visibility']) && $rule['visibility'] == SKINR_RULE_VISIBILITY_PHP && !$access) {
+    $form['visibility']['path']['visibility'] = array(
+      '#type' => 'value',
+      '#value' => SKINR_RULE_VISIBILITY_PHP,
+    );
+    $form['visibility']['path']['pages'] = array(
+      '#type' => 'value',
+      '#value' => isset($rule['pages']) ? $rule['pages'] : '',
+    );
   }
-  $form['rule']['visibility'] = array(
-    '#type' => 'radios',
-    '#title' => t('Show on specific pages'),
-    '#options' => $options,
-    '#default_value' => $rule['visibility'],
-    '#required' => TRUE,
+  else {
+    $options = array(
+      SKINR_RULE_VISIBILITY_NOTLISTED => t('All pages except those listed'),
+      SKINR_RULE_VISIBILITY_LISTED => t('Only the listed pages'),
+    );
+    $description = t("Specify pages by using their paths. Enter one path per line. The '*' character is a wildcard. Example paths are %blog for the blog page and %blog-wildcard for every personal blog. %front is the front page.", array('%blog' => 'blog', '%blog-wildcard' => 'blog/*', '%front' => '<front>'));
+
+    if (module_exists('php') && $access) {
+      $options += array(SKINR_RULE_VISIBILITY_PHP => t('Pages on which this PHP code returns <code>TRUE</code> (experts only)'));
+      $title = t('Pages or PHP code');
+      $description .= ' ' . t('If the PHP option is chosen, enter PHP code between %php. Note that executing incorrect PHP code can break your Drupal site.', array('%php' => '<?php ?>'));
+    }
+    else {
+      $title = t('Pages');
+    }
+    $form['visibility']['path']['visibility'] = array(
+      '#type' => 'radios',
+      '#title' => t('Show block on specific pages'),
+      '#options' => $options,
+      '#default_value' => isset($rule['visibility']) ? $rule['visibility'] : SKINR_RULE_VISIBILITY_NOTLISTED,
+    );
+    $form['visibility']['path']['pages'] = array(
+      '#type' => 'textarea',
+      '#title' => '<span class="element-invisible">' . $title . '</span>',
+      '#default_value' => isset($rule['pages']) ? $rule['pages'] : '',
+      '#description' => $description,
+    );
+  }
+
+  // Per-node visbility.
+  $form['visibility']['node_type'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Content types'),
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+    '#group' => 'visibility',
+    '#weight' => 5,
   );
-  $form['rule']['pages'] = array(
-    '#type' => 'textarea',
-    '#title' => t('Pages'),
-    '#default_value' => $rule['pages'],
-    '#description' => $description,
+  $form['visibility']['node_type']['types'] = array(
+    '#type' => 'checkboxes',
+    '#title' => t('Show block for specific content types'),
+    '#default_value' => $rule['node_types'],
+    '#options' => node_type_get_names(),
+    '#description' => t('Show this block only on pages that display content of the given type(s). If you select no types, there will be no type-specific limitation.'),
   );
 
-  $form['buttons']['save'] = array(
+  // Per-role visibility.
+  $role_options = array_map('check_plain', user_roles());
+  $form['visibility']['role'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Roles'),
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+    '#group' => 'visibility',
+    '#weight' => 10,
+  );
+  $form['visibility']['role']['roles'] = array(
+    '#type' => 'checkboxes',
+    '#title' => t('Show block for specific roles'),
+    '#default_value' => $rule['roles'],
+    '#options' => $role_options,
+    '#description' => t('Show this rule only for the selected role(s). If you select no roles, the rule will be visible to all users.'),
+  );
+
+  $form['actions'] = array('#type' => 'actions');
+  $form['actions']['submit'] = array(
     '#type' => 'submit',
-    '#value' => t('Save'),
+    '#value' => t('Save rule'),
   );
   if (isset($rule['rid'])) {
-    $form['buttons']['delete'] = array(
+    $form['actions']['delete'] = array(
       '#type' => 'submit',
       '#value' => t('Delete'),
       '#submit' => array('skinr_rule_delete_submit'),
@@ -227,16 +293,19 @@ function skinr_rule_edit($form, &$form_state, $rid = NULL) {
 }
 
 /**
- * Process skinr_rule_edit() submissions.
+ * Form submission handler for the rule configuration form.
+ *
+ * @see skinr_rule_edit()
  */
 function skinr_rule_edit_submit($form, &$form_state) {
   $rule = new stdClass();
   $rule->rid = !empty($form_state['values']['rid']) ? $form_state['values']['rid'] : NULL;
   $rule->rule_type = $form_state['values']['rule_type'];
   $rule->title = $form_state['values']['title'];
+  $rule->node_types = $form_state['values']['types'];
   $rule->roles = $form_state['values']['roles'];
-  $rule->visibility = $form_state['values']['visibility'];
-  $rule->pages = $form_state['values']['pages'];
+  $rule->visibility = (int) $form_state['values']['visibility'];
+  $rule->pages = trim($form_state['values']['pages']);
 
   skinr_rule_save($rule);
   // Set rule id, if we inserted a new rule to allow others to know what rule they're working with.
