diff --git a/.htaccess b/.htaccess
index 1890b7a4fba..12b0c33c7d3 100644
--- a/.htaccess
+++ b/.htaccess
@@ -38,6 +38,9 @@ ErrorDocument 500 /error.php
 # Various rewrite rules
 <IfModule mod_rewrite.c>
   RewriteEngine on
+  RewriteCond %{REQUEST_FILENAME} !-f
+  RewriteCond %{REQUEST_FILENAME} !-d
+  RewriteRule ^(.*)$ index.php?q=$1 [L] 
   RewriteRule ^blog/(.*) /index.php?q=blog/$1 [R]
 </IfModule>
 
diff --git a/includes/common.inc b/includes/common.inc
index 1ab18b8df6a..f98832b6b7a 100644
--- a/includes/common.inc
+++ b/includes/common.inc
@@ -107,6 +107,7 @@ function path_uri($brief = 0) {
   if (!$brief) {
     $path = "http://". $path;
   }
+
   return $path;
 }
 
@@ -482,13 +483,24 @@ function rewrite_old_urls($text) {
   ** and comment bodies.
   */
 
-  // rewrite 'node.php?id=<number>[&cid=<number>]' style URLs:
-  $text = eregi_replace("(node)\.php\?id=([[:digit:]]+)(&cid=)?([[:digit:]]*)", "?q=\\1/view/\\2/\\4", $text);
+  if (variable_get("clean_url", "1")) {
+    // rewrite 'node.php?id=<number>[&cid=<number>]' style URLs:
+    $text = eregi_replace("(node)\.php\?id=([[:digit:]]+)(&cid=)?([[:digit:]]*)", "\\1/view/\\2/\\4", $text);
 
-  // rewrite 'module.php?mod=<name>{&<op>=<value>}' style URLs:
-  $text = ereg_replace("module\.php\?(&?[[:alpha:]]+=([[:alnum:]]+))(&?[[:alpha:]]+=([[:alnum:]]+))(&?[[:alpha:]]+=([[:alnum:]]+))", "?q=\\2/\\4/\\6" , $text);
-  $text = ereg_replace("module\.php\?(&?[[:alpha:]]+=([[:alnum:]]+))(&?[[:alpha:]]+=([[:alnum:]]+))", "?q=\\2/\\4" , $text);
-  $text = ereg_replace("module\.php\?(&?[[:alpha:]]+=([[:alnum:]]+))", "?q=\\2" , $text);
+    // rewrite 'module.php?mod=<name>{&<op>=<value>}' style URLs:
+    $text = ereg_replace("module\.php\?(&?[[:alpha:]]+=([[:alnum:]]+))(&?[[:alpha:]]+=([[:alnum:]]+))(&?[[:alpha:]]+=([[:alnum:]]+))", "\\2/\\4/\\6" , $text);
+    $text = ereg_replace("module\.php\?(&?[[:alpha:]]+=([[:alnum:]]+))(&?[[:alpha:]]+=([[:alnum:]]+))", "\\2/\\4" , $text);
+    $text = ereg_replace("module\.php\?(&?[[:alpha:]]+=([[:alnum:]]+))", "\\2" , $text);
+  }
+  else {
+    // rewrite 'node.php?id=<number>[&cid=<number>]' style URLs:
+    $text = eregi_replace("(node)\.php\?id=([[:digit:]]+)(&cid=)?([[:digit:]]*)", "?q=\\1/view/\\2/\\4", $text);
+
+    // rewrite 'module.php?mod=<name>{&<op>=<value>}' style URLs:
+    $text = ereg_replace("module\.php\?(&?[[:alpha:]]+=([[:alnum:]]+))(&?[[:alpha:]]+=([[:alnum:]]+))(&?[[:alpha:]]+=([[:alnum:]]+))", "?q=\\2/\\4/\\6" , $text);
+    $text = ereg_replace("module\.php\?(&?[[:alpha:]]+=([[:alnum:]]+))(&?[[:alpha:]]+=([[:alnum:]]+))", "?q=\\2/\\4" , $text);
+    $text = ereg_replace("module\.php\?(&?[[:alpha:]]+=([[:alnum:]]+))", "?q=\\2" , $text);
+  }
 
   return $text;
 }
@@ -769,21 +781,42 @@ function form_weight($title = NULL, $name = "weight", $value = 0, $delta = 10, $
 }
 
 function url($url = NULL, $query = NULL) {
+  global $base_url;
 
-  if (isset($url)) {
-    if (isset($query)) {
-      return "?q=$url&amp;$query";
+  if (variable_get("clean_url", "1")) {
+    if (isset($url)) {
+      if (isset($query)) {
+        return "$base_url/$url?$query";
+      }
+      else {
+        return "$base_url/$url";
+      }
     }
     else {
-      return "?q=$url";
+      if (isset($query)) {
+        return "$base_url/?$query";
+      }
+      else {
+        return "$base_url";
+      }
     }
   }
   else {
-    if (isset($query)) {
-      return "?$query";
+    if (isset($url)) {
+      if (isset($query)) {
+        return "?q=$url&amp;$query";
+      }
+      else {
+        return "?q=$url";
+      }
     }
     else {
-      return "";
+      if (isset($query)) {
+        return "?$query";
+      }
+      else {
+        return "";
+      }
     }
   }
 }
@@ -812,14 +845,14 @@ function field_set($string, $name, $value) {
 }
 
 function link_page() {
-  global $custom_links;
+  global $custom_links, $base_url;
 
   if (is_array($custom_links)) {
     return $custom_links;
   }
   else {
     $links = module_invoke_all("link", "page");
-    array_unshift($links, "<a href=\"index.php\" title=\"". t("Return to the main page.") ."\">". t("home") ."</a>");
+    array_unshift($links, "<a href=\"$base_url\" title=\"". t("Return to the main page.") ."\">". t("home") ."</a>");
     return $links;
   }
 }
diff --git a/includes/conf.php b/includes/conf.php
index b4c97313ff7..f9b29e4c331 100644
--- a/includes/conf.php
+++ b/includes/conf.php
@@ -17,6 +17,13 @@
 
 $db_url = "mysql://drupal:drupal@localhost/drupal";
 
+#
+# Base URL:
+#
+#   The URL of your website's main page.
+#
+$base_url = "http://localhost";
+
 #
 # PHP settings:
 #
diff --git a/modules/admin.module b/modules/admin.module
index 29d49a2c28a..28a8aa1368a 100644
--- a/modules/admin.module
+++ b/modules/admin.module
@@ -20,7 +20,7 @@ function admin_admin() {
 }
 
 function admin_page() {
-  global $user;
+  global $user, $base_url;
 
   if (user_access("access administration pages")) {
     page_header();
@@ -30,6 +30,7 @@ function admin_page() {
     <html>
      <head>
       <title><?php echo variable_get("site_name", "drupal") . " " . t("administration pages"); ?></title>
+      <base href="<?php echo "$base_url/" ?>" />
       <link rel="stylesheet" type="text/css" media="print" href="misc/print.css" />
       <style type="text/css" title="layout" media="Screen">
         @import url("misc/admin.css");
diff --git a/modules/system.module b/modules/system.module
index 61a9d2d96dd..eac2ef928ba 100644
--- a/modules/system.module
+++ b/modules/system.module
@@ -57,6 +57,8 @@ function system_view_modules() {
   $output .= form_textfield(t("Anonymous user"), "anonymous", variable_get("anonymous", "Anonymous"), 55, 55, t("The name used to indicate anonymous users."));
   foreach (module_list() as $name) { if (module_hook($name, "page")) $pages[$name] = $name; }
   $output .= form_select(t("Default front page"), "site_frontpage", variable_get("site_frontpage", "node"), $pages, t("The home page displays content from this module (usually node)."));
+  $output .= form_select(t("Clean URLs"), "clean_url", variable_get("clean_url", 0), array(t("Disabled"), t("Enabled")), t("Enable or disable clean URLs.  If enabled, you'll need <code>ModRewrite</code> support.  See also the <code>.htaccess</code> file in Drupal's top-level directory."));
+
   $output .= "<hr />\n";
 
   // caching:
diff --git a/modules/system/system.module b/modules/system/system.module
index 61a9d2d96dd..eac2ef928ba 100644
--- a/modules/system/system.module
+++ b/modules/system/system.module
@@ -57,6 +57,8 @@ function system_view_modules() {
   $output .= form_textfield(t("Anonymous user"), "anonymous", variable_get("anonymous", "Anonymous"), 55, 55, t("The name used to indicate anonymous users."));
   foreach (module_list() as $name) { if (module_hook($name, "page")) $pages[$name] = $name; }
   $output .= form_select(t("Default front page"), "site_frontpage", variable_get("site_frontpage", "node"), $pages, t("The home page displays content from this module (usually node)."));
+  $output .= form_select(t("Clean URLs"), "clean_url", variable_get("clean_url", 0), array(t("Disabled"), t("Enabled")), t("Enable or disable clean URLs.  If enabled, you'll need <code>ModRewrite</code> support.  See also the <code>.htaccess</code> file in Drupal's top-level directory."));
+
   $output .= "<hr />\n";
 
   // caching:
diff --git a/themes/marvin/marvin.theme b/themes/marvin/marvin.theme
index d1361857cd2..694d163f0bd 100644
--- a/themes/marvin/marvin.theme
+++ b/themes/marvin/marvin.theme
@@ -27,13 +27,14 @@
    }
 
    function header($title = "") {
-     global $HTTP_USER_AGENT;
+     global $HTTP_USER_AGENT, $base_url;
     ?>
      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      <html>
      <head>
       <?php print theme_head($main); ?>
       <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+      <base url="<?php echo "$base_url/" ?>" />
       <title>
        <?php
          if ($title) {
diff --git a/themes/unconed/unconed.theme b/themes/unconed/unconed.theme
index 77d02d5ccc3..7fddff88ff2 100644
--- a/themes/unconed/unconed.theme
+++ b/themes/unconed/unconed.theme
@@ -45,12 +45,14 @@
    }
 
    function header($title = "") {
+     global $base_url;
      srand((double)microtime()*1000000);
     ?>
      <HTML>
      <HEAD>
       <?php print theme_head($main); ?>
       <TITLE><?php echo ($title ? ($title . " - ") : "") . variable_get(site_name, "drupal"); ?></TITLE>
+      <BASE HREF="<?php echo "$base_url/"; ?>" />
       <STYLE type="text/css">
        <!--
         TABLE { border-width: 0; }
diff --git a/themes/xtemplate/xtemplate.theme b/themes/xtemplate/xtemplate.theme
index 4ab3b7d745d..246acdc832b 100644
--- a/themes/xtemplate/xtemplate.theme
+++ b/themes/xtemplate/xtemplate.theme
@@ -60,9 +60,12 @@ class Theme_xtemplate extends BaseTheme {
   }
 
   function header($title = "") {
+    global $base_url;
+
     $this->template->assign(array(
       "title" => ($title ? $title." | ". variable_get("site_name", "drupal") : variable_get("site_name", "drupal") ." | ". variable_get("site_slogan", "")),
       "head" => theme_head(),
+      "base" => "$base_url/",
       "links" => $this->links(link_page())
     ));
 
diff --git a/themes/xtemplate/xtemplate.xtmpl b/themes/xtemplate/xtemplate.xtmpl
index 4c795cd5620..194a67c90f0 100644
--- a/themes/xtemplate/xtemplate.xtmpl
+++ b/themes/xtemplate/xtemplate.xtmpl
@@ -5,6 +5,7 @@
 
 <head>
   <title>{title}</title>
+  <base href="{base}" />
   <style type="text/css" media="all">
     @import "themes/xtemplate/xtemplate.css";
   </style>