Custom Permalinks for WordPress under IIS

A permalink, or permanent link, is a URL that points to a specific blog or forum entry after it has passed from the front page to the archives.

Gosh, those permalinks can be so important for search engine optimization.  If you’ve taken WordPress out-of-the-box, you might find it curious that pages and posts, by default, are referenced by a quirky /?p=<postID> instead of a more SEO-friendly syntax.

As an example: vs.

As you probably can tell, even this site is powered by WordPress (as at time of writing around version 3.2.1) so my pain in supporting a custom permalink structure is all too recent (but, if you are in the same situation – quite fortunate).

Now my pain is partially augmented by the fact that (I’d reasonably assert) most WordPress instances are installed on an Apache web server.  Mine (and probably a few others) is actually hosted on Internet Information Services (IIS) on a Windows Server.  Most of the supporting documentation on how to support customized permalinks relates to adjusting on Apache and the .htaccess approach.

This isn’t valid for an IIS hosted WordPress blog.

You might even consider that IIS makes supporting custom permalinks a little easier – but no less baffling.  Last night I migrated one of my WordPress sites across to a new permalink structure /year/post-title/post-id/ (such as in the example above).  I was following steps from a forum or some such place.  After a little digging around it all seemed to work fine.

Then, I tried to make the exact same configuration changes to this site, and was rewarded with a blank page.  Interesting.  It is (of course) fixed now (many thanks to the consult from @pwae).

So now I’m going to document what I did, in case it helps you.

You need three essential settings:

  1. Permalinks settings panel in the (WordPress) Administration console
  2. Access to the IIS server (or to the site) using IIS Manager (to change both version 6.x and 7.x)
  3. A custom redirect page

First, you should set up the redirect page.  This will help all the traffic which is referring to the old ?p=<ID> format find its way to the newly defined structure.  I’ve added the page I came across on this site (which is missing a brace in their example, so better to use mine).  It’s a PHP file which you must map as the 404 page handler (for resource not found errors):

// Default file for WordPress site, generally "index.php"
$wpdefault = ‘index.php’;
// The name of this file.
$tempfile = ‘404_wp.php’;
$_SERVER[‘SCRIPT_FILENAME’] = str_replace($tempfile, $wpdefault, $_SERVER[‘SCRIPT_FILENAME’]);
$_SERVER[‘ORIG_PATH_INFO’] = str_replace($tempfile, $wpdefault, $_SERVER[‘ORIG_PATH_INFO’]);
$_SERVER[‘SCRIPT_NAME’] = str_replace($tempfile, $wpdefault, $_SERVER[‘SCRIPT_NAME’]);
$_SERVER[‘PHP_SELF’] = str_replace($tempfile, $wpdefault, $_SERVER[‘PHP_SELF’]);
$_SERVER[‘PATH_INFO’] = false;
$querystr =& $_SERVER[‘QUERY_STRING’]; $requesturl =& $_SERVER[‘REQUEST_URI’];
$position = strrpos($querystr, ‘://’);
$position = strpos($querystr, ‘/’, $position + 4);
$_SERVER[‘URL’] = $requesturl = substr($querystr, $position);
$querystr = trim(stristr($requesturl, ‘?’), ‘?’);
// Required for WordPress 2.8+
$_SERVER[‘HTTP_X_ORIGINAL_URL’] = $requesturl;
// Fix GET vars
foreach ( $_GET as $var => $val ) {
if ( substr($var, 0, 3) == ‘404’) {
if ( strstr($var, ‘?’) ) {
$nv = substr($var, strpos($var, ‘?’) + 1);
$_GET[$nv] = $val;}

Now if you copy this code into a file and save it as 404_wp.php (as suggested in the source article), upload it to your IIS server site in the same location as your wp-config.php file is (perhaps the site root?).

Gain access to your IIS server (or equivalent console for managing error/event mapping) and assign your 404 handler with the URL “/404_wp.php” (assuming the file is in your site root).

Internet Information Services v5.x/6.x

On IIS 5.x and 6.x this is done this way:

  1. Right click your site in IIS\Web Sites\<your site>
  2. In the properties dialog, click on Custom Errors
  3. Scroll to 404 and click Edit
  4. Change Message Type to URL
  5. Insert the path to the 404_wp.php file (don’t forget a forward slash at the start)

image image

[screen grabs above C/- ]

Internet Information Services v7.x

On IIS 7.x it’s a little different:

  1. Select your site from the tree on the left hand side
  2. In the “Features View” double click on “Error Pages”
  3. Select 404 and on the right hand side action window click “Edit”
  4. Select the “Execute a URL on this site” radio button
  5. Enter the absolute URI to your 404_wp.php file

image image

Next, time to configure that custom permalink format:

  1. Log into the Admin site
  2. Select “Permalink” under the Settings menu
  3. Select “Custom Structure” radio button
  4. Add your custom permalink structure – mine is: /%year%/%postname%/%post_id%/

image image

Once you hit the “Save Changes” button, all your posts will resolve according to the permalink structure you’ve set.

All your old references should resolve based on the previous format too.




My problem here was the default document order.  You might have to ensure that only one matching document is in your site root, and ensure it loads by default once you have implemented the custom 404 redirection.

Leave a comment

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

6 thoughts on “Custom Permalinks for WordPress under IIS”