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:
http://www.sanderstechnology.com/?p=9864 vs.
http://www.sanderstechnology.net/2008/breaking-news-ssl-broken/9864/
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:
- Permalinks settings panel in the (WordPress) Administration console
- Access to the IIS server (or to the site) using IIS Manager (to change both version 6.x and 7.x)
- 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):
<?php
// 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;}
unset($_GET[$var]);}
break;}
include($wpdefault);
?>
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:
- Right click your site in IIS\Web Sites\<your site>
- In the properties dialog, click on Custom Errors
- Scroll to 404 and click Edit
- Change Message Type to URL
- Insert the path to the 404_wp.php file (don’t forget a forward slash at the start)
[screen grabs above C/- http://wpveda.com/change-permalink-structure-iis-6-server/ ]
Internet Information Services v7.x
On IIS 7.x it’s a little different:
- Select your site from the tree on the left hand side
- In the “Features View” double click on “Error Pages”
- Select 404 and on the right hand side action window click “Edit”
- Select the “Execute a URL on this site” radio button
- Enter the absolute URI to your 404_wp.php file
Next, time to configure that custom permalink format:
- Log into the Admin site
- Select “Permalink” under the Settings menu
- Select “Custom Structure” radio button
- Add your custom permalink structure – mine is: /%year%/%postname%/%post_id%/
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.
Hopefully.
Troubleshooting:
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.
6 thoughts on “Custom Permalinks for WordPress under IIS”
Is there really no pattern-matching redirection functionality in ISS? Seems a bit kludgey to catch it at the 404 stage. ModRewrite is so critical to me, I could not really imagine life without.
In IIS 5.x and 6.x I believe you’d have to write an ISAPI filter.
IIS 7.x has much more functionality, but I’m hosting on pre-IIS 7.x so I haven’t looked into it (yet).
I get this error. I am with GoDaddy. Parse error: syntax error, unexpected ‘:’ in D:\Hosting\3798789\html\laf\blog\404_wp.php on line 12
All is good as long as I use the default permalink but when I choose a preset or create a custom one, I got the 404 msg. Now after having followed the above, I get that line 12 error.
I have never had this issue before. I could also change the permalinks at will when fiddling around with options and it would chnage everything according on the fly.
Sorry about the late reply. Seems a tad odd, I can’t see why a colon on line 12 (://) would be causing issues. I wonder if it might need escaping somehow? Can you post what you’ve got on line 12?
No need to install any ISAPI filter to remove the index.php from WordPress permalinks.No need of .htaccess file..Use these simple steps to WordPress Permalinks in IIS 6.0 using Custom 404 Redirect for Windows Shared hosting/manas hosting or any windows shared hosting.
http://dotnetcodebytes.blogspot.com/2011/11/remove-indexphp-from-wordpress-on.html
Hey Mukesh, why would you post a link to an article you obviously copied from this site, didn’t add anything of value to, then provide no attribution? Are you trying to get extra traffic from here? What’s the point, your not helping anyone!