Index: wikitools.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/wikitools/wikitools.module,v
retrieving revision 1.4.2.1
diff -u -r1.4.2.1 wikitools.module
--- wikitools.module	22 Feb 2008 16:46:14 -0000	1.4.2.1
+++ wikitools.module	23 Feb 2008 18:31:15 -0000
@@ -56,8 +56,8 @@
     $callbacks['node/%node/delete']['page callback'] = 'wikitools_delete_protection_delete_confirm';
     $callbacks['node/%node/delete']['page arguments'] = array(1);
   }
-  // Only hijack freelinking path if an argument is specified, otherwise let the freelinking page show.
-  if (wikitools_hijack_freelinking()) {
+  // Hijack all freelinking links
+  if (module_exists('freelinking') && wikitools_hijack_freelinking()) {
     $callbacks['freelinking/%'] = array(
       'page callback' => 'wikitools_handle_request',
       'access arguments' => array('access content'),
@@ -129,21 +129,76 @@
   $form['wikitools_disallowed_characters'] = array(
     '#type' => 'textfield',
     '#title' => t('Disallowed characters in titles'),
-    '#description' => t('A list of characters which are not allowed in the title of a wiki page. This setting is important for the wikilink feature to work. Set it so that your input syntax will not be confused by titles. Make sure you don\'t enter a space character unless you really want to disallow spaces in titles. Leave empty to disable this feature.'),
+    '#description' => t('Leave empty to disable this feature. If "/" is specified, subpages can be used as URL suffixes instead of a query string, which is prettier.'),
     '#default_value' => wikitools_disallowed_characters(),
   );
-  $form['wikitools_hijack_freelinking'] = array(
+  if (module_exists('freelinking')) {
+    $form['wikitools_hijack_freelinking'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Hijack freelinking filter'),
+      '#default_value' => wikitools_hijack_freelinking(),
+      '#description' => t('If you activate this option, the links of the freelinking filter will be processed by the wikitools module rather than the freelinking module. When active, a link to <em>freelinking/Page Name</em> behaves exactly as a link to <em>wikipath/Page Name</em>.'),
+    );
+  }
+  $form['subpages'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Subpages'),
+    '#description' => t('Subpages can be appended to a URL (either directly or via a query string) and will redirect the user to the named subpage. This setting changes depending on which disallowed characters are specified. Examples are <em>wikipath/Page/edit</em> or <em>wikipath/Page?wt_action=edit</em>, depending on settings.'),
+  );
+  
+  $desc = '';
+  $title = '';
+  $rv = '';
+  if (strpos(wikitools_disallowed_characters(), '/') !== FALSE) {
+    $title = t('Enable URL suffixes');
+    $rv = 'url';
+    $desc = t('With URL suffixes, you can append the subpage to the URL. For example  <em>wikipath/Page/edit</em>.');
+  }
+  else {
+    $title = t('Enable query string');
+    $rv = 'query';
+    $desc = t('With query strings, you can append the subpage as a query. For example <em>wikipath/Page?wt_action=edit</em>.');
+  }
+
+  $form['subpages']['checkboxes'] = array(
+    '#value' => '<h4>'. t('Activation') .'</h4>'
+  );
+  
+  $form['subpages']['wikitools_subpages_enabled'] = array(
     '#type' => 'checkbox',
-    '#title' => t('Hijack freelinking filter'),
-    '#default_value' => wikitools_hijack_freelinking(),
-    '#description' => t('If you activate this option, the links of the freelinking filter will be processed by the wikitools module rather than the freelinking module. When active, a link to <em>freelinking/Page Name</em> behaves exactly as a link to <em>wikipath/Page Name</em>.'),
+    '#title' => $title,
+    '#description' => $desc,
+    '#return_value' => $rv,
+    '#default_value' => variable_get('wikitools_subpages_enabled', array()),
   );
+
   $form = system_settings_form($form);
   // Rebuild the menu after updating the settings.
   $form['#submit'][] = 'menu_rebuild';
   return $form;
 }
 
+/**
+ * Make sure that settings are saved correctly. Subpages is a trinary option:
+ * 1) Subpages off
+ * 2) Subpages type URL on
+ * 3) Subpages type QUERY on
+ * 
+ * Make sure that settings are saved correctly to reflect that.
+ */
+function wikitools_admin_settings_validate($form_id, &$form_state) {
+  // If URL suffixes are allowed
+  if (strpos($form_state['values']['wikitools_disallowed_characters'], '/') !== FALSE) {
+    if ($form_state['values']['wikitools_subpages_enabled']) {
+      $form_state['values']['wikitools_subpages_enabled'] = 'url';
+    }
+  }
+  // If query string is allowed
+  else if ($form_state['values']['wikitools_subpages_enabled']) {
+    $form_state['values']['wikitools_subpages_enabled'] = 'query';
+  }
+}
+
 /*
  * Settings
  */
@@ -293,45 +348,75 @@
   variable_set('wikitools_hijack_freelinking', $value);
 }
 
+/**
+ * Are subpages enabled with URL suffixes?
+ * Can return 0, 'url', or 'query'
+ */
+function wikitools_subpages_enabled() {
+  return variable_get('wikitools_subpages_enabled', 0);
+}
+
 /*
  * Operations
  */
 
 /**
+ * Decode page name given via URL.
+ */
+function wikitools_decode_page_name($encoded_page_name) {
+  $page_name = trim(urldecode($encoded_page_name));
+  if (wikitools_treat_underscore_as_space()) {
+    $page_name = str_replace('_', ' ', $page_name);
+  }
+  if (wikitools_treat_dash_as_space()) {
+    $page_name = str_replace('-', ' ', $page_name);
+  }
+  return $page_name;
+}
+
+/**
  * Menu callback for wiki path.
  * This function is called if a page without an alias is called below the wiki path.
  */
 function wikitools_handle_request() {
-  // Calculate index of first path argument after wiki path if specific position wasn't passed in.
+  $output = '';
+  // Create list of path parts.
+  $args = explode('/', $_GET['q']);
+
+  // Calculate index of first path argument after wiki path.
   if (arg(0) != 'freelinking') {
     $i = count(explode('/', wikitools_wiki_path()));
   }
   else {
     $i = 1;
   }
-  if (arg($i)) {
-    // Save the path arguments after the wiki path as page name and put the slashes back.
-    $page_name = arg($i++);
-    while (arg($i)) {
-      $page_name .= '/'. arg($i);
-      $i++;
+
+  // Determine subpage.
+  $subpage = NULL;
+  if ($subpage_setting = wikitools_subpages_enabled()) {
+    if ($subpage_setting == 'query') {
+      if (isset($_GET['wt_action'])) {
+        $subpage = $_GET['wt_action'];
+      }
     }
+    else if ($subpage_setting == 'url') {
+      if (count($args)-$i > 1) {
+        $subpage = array_pop($args);
+      }
+    }
+  }
+
+  // Determine page name.
+  if (isset($args[$i])) {
+    $page_name = wikitools_decode_page_name(implode('/', array_slice($args, $i)));
   }
   else {
     // Use default page title if only wiki path is entered.
     $page_name = wikitools_main_page_title();
   }
-  // Decode page name and remove white space.
-  $page_name = trim(urldecode($page_name));
-  if (wikitools_treat_underscore_as_space()) {
-    $page_name = str_replace('_', ' ', $page_name);
-  }
-  if (wikitools_treat_dash_as_space()) {
-    $page_name = str_replace('-', ' ', $page_name);
-  }
-  $node_types = wikitools_node_types();
-  $output = '';
+
   // Don't do anything if no node types are active or no page name is available
+  $node_types = wikitools_node_types();
   if (count($node_types) && $page_name) {
     // Try to find the current page with this name.
     $result = db_query("SELECT nid, type FROM {node} WHERE LOWER(title) = LOWER('%s')", $page_name);
@@ -344,7 +429,12 @@
     if (count($found_nodes) == 1) {
       // Single match for title.
       $node = current($found_nodes);
-      drupal_goto("node/$node->nid");
+      if ($subpage) {
+        drupal_goto("node/$node->nid/$subpage");
+      }
+      else {
+        drupal_goto("node/$node->nid");
+      }
     }
     else if (count($found_nodes) > 1) {
       // Multiple match for title.
@@ -394,6 +484,7 @@
  */
 function wikitools_node_validate($node) {
   if (wikitools_type_affected($node->type)) {
+    // Check for unique titles.
     if (wikitools_enforce_unique_titles()) {
       // Build node type condition.
       $types_clause = NULL;
@@ -420,8 +511,8 @@
         form_set_error('title', t('A <a href="@page_url">page</a> with this name alredy exists.', array('@page_url' => url("node/$nid"))));
       }
     }
-    $disallowed_characters = wikitools_disallowed_characters();
-    if ($disallowed_characters) {
+    // Check for disallowed characters in title.
+    if ($disallowed_characters = wikitools_disallowed_characters()) {
       for ($i = 0; $i < strlen($node->title); $i++) {
         if (strpos($disallowed_characters, $node->title[$i]) !== FALSE) {
           form_set_error('title', t('The character %c is not allowed in a title', array('%c' => $node->title[$i])));
