? js/skinr-ui.js
Index: skinr.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/skinr/skinr.install,v
retrieving revision 1.9
diff -u -p -r1.9 skinr.install
--- skinr.install	19 Oct 2010 18:30:31 -0000	1.9
+++ skinr.install	27 Oct 2010 00:06:30 -0000
@@ -98,6 +98,13 @@ function skinr_schema() {
         '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.',
       ),
+      'node_types' => array(
+        'type' => 'text',
+        'size' => 'normal',
+        'not null' => FALSE,
+        'serialize' => TRUE,
+        'description' => 'A serialized array of node types for this record.',
+      ),
     ),
     'primary key' => array('rid'),
   );
@@ -383,3 +390,18 @@ function skinr_update_7003() {
     db_create_table('skinr_skins', $schema['skinr_skins']);
   }
 }
+
+/**
+ * Add the content type field to the skinr_rules table.
+ */
+function skinr_update_7004() {
+  if (db_table_exists('skinr_rules')) {
+    db_add_field('skinr_rules', 'node_types', array(
+      'type' => 'text',
+      'size' => 'normal',
+      'not null' => FALSE,
+      'serialize' => TRUE,
+      'description' => 'A serialized array of node types for this record.',
+    ));
+  }
+}
Index: skinr.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/skinr/skinr.module,v
retrieving revision 1.28
diff -u -p -r1.28 skinr.module
--- skinr.module	15 Oct 2010 07:06:17 -0000	1.28
+++ skinr.module	27 Oct 2010 00:06:31 -0000
@@ -310,6 +310,7 @@ function skinr_rule_load_multiple($rids 
   }
   foreach ($select->execute() as $rule) {
     $rule->roles = unserialize($rule->roles);
+    $rule->node_types = unserialize($rule->node_types);
     $rules[$rule->rid] = $rule;
   }
   return $rules;
@@ -336,10 +337,25 @@ function skinr_rule_visible($rid) {
   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 the roles visibility.
+    if (!empty($rule->roles) && ($user->uid != 1) && !count(array_intersect(array_keys($user->roles), $rule->roles))) {
       return FALSE;
     }
 
+    // Check the content type visibility.
+    // Return false if a node type is set and we're not on a node page,
+    // we're on a different node type, or we're on the add/edit page.
+    if (!empty($rule->node_types)) {
+      if ((arg(0) != 'node' || (arg(0) == 'node' && (arg(1) == 'add' || arg(1) == 'edit')))) {
+        return FALSE;
+      }
+
+      $node = menu_get_object();
+      if (!empty($node) && isset($rule->node_types[$node->type]) && empty($rule->node_types[$node->type])) {
+        return FALSE;
+      }
+    }
+
     // Match path if necessary
     if ($rule->pages) {
       if ($rule->visibility < 2) {
@@ -1130,4 +1146,4 @@ function skinr_handler($type, $op, $hand
         return $handler($op, $a3, $a4);
     }
   }
-}
\ No newline at end of file
+}
Index: skinr_ui.rules.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/skinr/skinr_ui.rules.inc,v
retrieving revision 1.6
diff -u -p -r1.6 skinr_ui.rules.inc
--- skinr_ui.rules.inc	27 May 2010 14:07:17 -0000	1.6
+++ skinr_ui.rules.inc	27 Oct 2010 00:06:31 -0000
@@ -131,6 +131,7 @@ function skinr_rule_edit($form, &$form_s
       'roles' => $form_state['values']['roles'],
       'visibility' => $form_state['values']['visibility'],
       'pages' => $form_state['values']['pages'],
+      'node_types' => $form_state['values']['node_types'],
     );
   }
   elseif(!is_null($rid) && $rule = skinr_rule_load($rid)) {
@@ -147,6 +148,7 @@ function skinr_rule_edit($form, &$form_s
       'roles' => array(),
       'visibility' => 0,
       'pages' => '',
+      'node_types' => array(),
     );
   }
 
@@ -162,43 +164,18 @@ function skinr_rule_edit($form, &$form_s
     '#type' => 'hidden',
     '#value' => $rule['rule_type'],
   );
+
   $form['rule']['rule_type_displayed'] = array(
     '#type' => 'item',
     '#title' => t('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.'),
-  );
-
-  // 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>'));
-
-  // 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 ?>'));
-  }
   $form['rule']['visibility'] = array(
-    '#type' => 'radios',
-    '#title' => t('Show on specific pages'),
-    '#options' => $options,
-    '#default_value' => $rule['visibility'],
-    '#required' => TRUE,
-  );
-  $form['rule']['pages'] = array(
-    '#type' => 'textarea',
-    '#title' => t('Pages'),
-    '#default_value' => $rule['pages'],
-    '#description' => $description,
+    '#type' => 'vertical_tabs',
+    '#attached' => array(
+      'js' => array(drupal_get_path('module', 'skinr_ui') . '/js/skinr-ui.js'),
+    ),
   );
 
   $form['buttons']['save'] = array(
@@ -213,6 +190,80 @@ function skinr_rule_edit($form, &$form_s
     );
   }
 
+  // Per-path visibility.
+  $form['rule']['visibility']['path'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Pages'),
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+    '#group' => 'visibility',
+    '#weight' => 0,
+    '#attributes' => array('id' => 'path'),
+  );
+
+  $access = user_access('use PHP for settings');
+  $options = array(
+    0 => t('All pages except those listed'),
+    1 => 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(2 => 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['rule']['visibility']['path']['visibility'] = array(
+    '#type' => 'radios',
+    '#title' => t('Show rule on specific pages'),
+    '#options' => $options,
+    '#default_value' => $rule['visibility'],
+  );
+  $form['rule']['visibility']['path']['pages'] = array(
+    '#type' => 'textarea',
+    '#title' => '<span class="element-invisible">' . $title . '</span>',
+    '#default_value' => $rule['pages'],
+    '#description' => $description,
+  );
+
+  $form['rule']['visibility']['node_type'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Content types'),
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+    '#group' => 'visibility',
+    '#weight' => 5,
+    '#attributes' => array('id' => 'node-type'),
+  );
+  $form['rule']['visibility']['node_type']['node_types'] = array(
+    '#type' => 'checkboxes',
+    '#title' => t('Show rule for specific content types'),
+    '#options' => node_type_get_names(),
+    '#default_value' => $rule['node_types'] ? $rule['node_types'] : array(),
+    '#description' => t('Show this rule only on pages that display content of the given type(s). If you select no types, there will be no type-specific limitation.'),
+  );
+
+  $role_options = array_map('check_plain', user_roles());
+  $form['rule']['visibility']['role'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Roles'),
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+    '#group' => 'visibility',
+    '#weight' => 10,
+    '#attributes' => array('id' => 'role'),
+  );
+  $form['rule']['visibility']['role']['roles'] = array(
+    '#type' => 'checkboxes',
+    '#title' => t('Show rule for specific roles'),
+    '#options' => $role_options,
+    '#default_value' => $rule['roles'],
+    '#description' => t('Show this rule only for the selected role(s). If you select no roles, the rule will be visible to all users.'),
+  );
+
   return $form;
 }
 
@@ -224,6 +275,7 @@ function skinr_rule_edit_submit($form, &
   $rule->roles = $form_state['values']['roles'];
   $rule->visibility = $form_state['values']['visibility'];
   $rule->pages = $form_state['values']['pages'];
+  $rule->node_types = $form_state['values']['node_types'];
 
   skinr_rule_save($rule);
   // Set rule id, if we inserted a new rule to allow others to know what rule they're working with.
