WordPress Pretty Permalinks on IIS without mod rewrite

wordpress-4-1Permalinks are the URLs to an individual post, category, page, etc. These links generally take the form of index.php?p=444 (or some number). Pretty Permalinks are the same URLs crafted to make sense to the user. Apache offers this ability, though generally not set by default. IIS through version 6 (Windows 2003) does not offer this. There are ISAPI filters both paid and free that permit the use of “pretty” permalinks.

However, the use of ISAPI filters is great if you have access to the web server, if you are like many who have their sites hosted on a shared IIS server, then this is not an option.

There is a solution that has been made available. All this does is fix the REQUEST_URI and PATH_INFO variables and then include index.php, WordPress will do the rest. It doesn’t duplicate functionality already available in WordPress and it doesn’t have the overhead of another http request for every page hit.

  1. Create the file wp-404-handler.php in your base WordPress folder.
    Note: There are several variations of this file, I tested each, until I found one that worked for my configuration.

    A four line version (worked for me) (source)

    <?php
    $_SERVER&#91;'REQUEST_URI'&#93; = substr($_SERVER&#91;'QUERY_STRING'&#93;, strpos($_SERVER&#91;'QUERY_STRING'&#93;, ':80')+3);
    $_SERVER&#91;'PATH_INFO'&#93; = $_SERVER&#91;'REQUEST_URI'&#93;;
    include('index.php');
    ?>

    A nine line version (works for others) (source)

    <?php
    $qs = $_SERVER&#91;'QUERY_STRING'&#93;;
    $pos = strrpos($qs, '://');
    $pos = strpos($qs, '/', $pos + 4);
    _SERVER&#91;'REQUEST_URI'&#93; = substr($qs, $pos);
    $_SERVER&#91;'PATH_INFO'&#93; = $_SERVER&#91;'REQUEST_URI'&#93;;
    include('index.php');
    ?>

    A six line version (alt. source)

    <?php
    $my_wp_url = &ldquo;http://&rdquo; . $_SERVER&#91;'SERVER_NAME'&#93; . &ldquo;/wordpress&rdquo;;
    $_SERVER&#91;'REQUEST_URI'&#93; = substr($_SERVER&#91;'QUERY_STRING'&#93;, strpos($_SERVER&#91;'QUERY_STRING'&#93;, $my_wp_url)+strlen($my_wp_url));
    $_SERVER&#91;'PATH_INFO'&#93; = $_SERVER&#91;'REQUEST_URI'&#93;;
    include(&rsquo;index.php&rsquo;);
    ?>

    Note: Edit “/wordpress” to reflect your WordPress installation, like “/blog” or “/wp”.

  2. Set your site 404 page to point to wp-404-handler.php. Most control panels (image below is an example using Helm) at web hosts allow you to do this. If you’ve got the option to select between FILE and URL then choose URL.

    wp-error

    However, If you have access to the IIS server, then through the IIS Manager, create a custom 404 handler. Open the IIS Management snap-in and right-click on the web site you want to modify and select Properties. Click the Custom Errors tab and scroll down to the entry for 404 errors. Click the Edit Properties button and change the Message Type to URL, then type in the relative URL to your wp-404-handler.php file, in my case “/wp/wp-404-handler.php”. Then restart IIS.

    wp-error5

  3. In the WordPress admin page, go to Options > Permalinks , and select Custom with the desired pattern, like ones below.
    /%year%/%monthnum%/%day%/%postname%/
    /%year%/%monthnum%/%postname%/
  4. Done.

Results
I have tested this on a Windows 2003 server, IIS6, non-hosted box with WordPress 2.7 and on a Windows 2003 server, IIS6, hosted box through a Helm interface with WordPress 2.6.2. I did successfully implement the first (four line version) solution without any problems. This solution does work for a root installation; however, I could not use this solution for a sub-domain or for more than one blog. In conclusion, if you have one blog, this is the solution for you. If more than one blog or sub-domains, consider a different hosting domain that uses Apache.