You can download SilverStripe from this page: http://www.silverstripe.com/silverstripe-web-application-framework/. After downloading please install CMS according to installation instructions provided by vendor.
Actually, SE-friendly feature is enabled by default. But SilverStripe does not originally support IIS and ISAPI_Rewrite. On the first page of the installation you may see this text:
If you open your web-site after SilverStripe installation, you will see the note that mod_rewrite is not enabled. Actually, SilverStripe tries to find mod_rewrite (only), and if the search is successful, SilverStripe automatically creates rules in .htaccess file, and you get CMS working with SE-friendly URLs!
Thus under IIS we need to do some hacking. Let’s just disable the check for mod_rewrite.
Please go to SilverStripe installation folder and open rewritetest.php file. Please find this code:
$testrewriting = file_get_contents($location);
if($testrewriting == 'OK') {
return true;
}
And comment is out as follows:
//$testrewriting = file_get_contents($location);
//if($testrewriting == 'OK') {
return true;
//}
So we just commented the check and left only return true and .htaccess configuration file required to run SEF URLs is already in place.
Done! Now you can use SilverStripe with pretty SE-friendly URLs powered by ISAPI_Rewrite.
You can download MW from this page: http://www.mediawiki.org/wiki/Download. After downloading please install MW according to installation instructions provided by the vendor.
Default MediaWiki URLs look like www.yousite.com/index.php?title=TITLE, but you can change them by using two configuration variables in LocalSettings.php:
$wgScript and $wgArticlePath.
In this article we will try to make
simple SEO-friendly urls like www.yousite.com/TITLE.
So, please open LocalSettings.php document (it is located in MediaWiki root folder) and append this code:
$wgScript = "";
$wgArticlePath = "$wgScript/$1";
Please note! The $wgScript variable must contain path to your MW folder. For example, if your MW installation is
C:\inetpub\wwwroot\mediawiki,
then you must write $wgScript = "/mediawiki", or if your MW installation is
C:\inetpub\wwwroot\, then you must write $wgScript = "".
Now please create .htaccess file in the installation folder of MediaWiki and put these rules into it:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?title=$1 [NC,L,QSA]
Done! Now you can use MediaWiki with pretty SE-friendly URLs.
]]>
You can download Drupal from official web site: http://drupal.org/. Please install Drupal according to installation instructions provided by vendor.
Please note! In the installation wizard you can see the configuration for enabling SE-friendly URLs, but with IIS you can’t use it because Drupal blocks controls as shown on this picture:
Please just leave it as is, it is possible to change this setting later.
Please find the file %PATH_TO_DRUPAL%/sites/default/settings.php, where %PATH_TO_DRUPAL% is the root of Drupal’s installation folder. Open this document and append the code given below:
$conf[ 'clean_url' ] = 1;
Then please open .htaccess file located in the root folder of Drupal. There are many rules but only some of them are intended for ISAPI_Rewrite, others are for Apache Web Server.
Please remove all rules from .htaccess file and put these:
RewriteEngine on
# Modify the RewriteBase if you are using Drupal in a subdirectory or in a
# VirtualDocumentRoot and the rewrite rules are not working properly.
# For example if your site is at http://example.com/drupal uncomment and
# modify the following line:
# RewriteBase /drupal
#
# If your site is running in a VirtualDocumentRoot at http://example.com/,
# uncomment the following line:
# RewriteBase /
# Rewrite URLs of the form 'x' to the form 'index.php?q=x'.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
Actually these are default Drupal rules for Apache mod_rewrite configuration and we just cut them from default .htaccess file.
Done! Now you can use Drupal CMS with pretty SEO-friendly URLs.
You can download WordPress from this web page: http://wordpress.org/download/.
Please don’t use versions lower than 2.6.1, because they will not work properly with ISAPI_Rewrite 3.
After downloading please install WordPress according to the installation instructions by the vendor. Note that in the installation wizard you may allow your blog to appear in search engines. This action enables indexing and will probably be important for you.
By default SE-friendly URLs are disabled. To enable this feature please go to WordPress administration panel. On the main page of administration panel please select “Settings” tab:
Now please select “Permalinks” tab. On the opened page you can see some default schemes of prettifying your URLs.
You may choose necessary scheme but notice that WordPress doesn’t use .htaccess file and ISAPI_Rewrite to process these permalinks. You will need to write your own rules.
Let’s write some simple rules for WordPress using ISAPI_Rewrite. Open “Permalinks” configuration as described above. Select “Custom Structure” radio box, and in adjacent field write /%post_id%/%postname% as shown on this picture:
Please save changes. %post_id% and %postname% are special tag names. You can read more about tags here: http://codex.wordpress.org/Using_Permalinks. So we have configuration for URLs like http://domain.com/1/my-great-post, and now we need to write some rules in .htaccess file. Please create .htaccess file in the root folder of WordPress and write the following code into it:
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(\d+)/[^/]+/?$ index.php?p=$1 [NC,L]
These rules rewrite requests like /1/my-great-post to those like index.php?p=1, but only if no such physical file of folder exist.
Done! Now you can use your WordPress blog with pretty URLs!
You can download Mambo from this page: http://mambo-code.org/gf/project/mambo/frs/. After downloading please install Mambo according to installation instructions provided by vendor.
By default SE-friendly URLs are disabled. To enable this feature please go to Mambo administration panel. On the main page of administration panel please select “Global Configuration”
On the opened page you can see few tabs. Please find “SEO” tab and select it:
Now you can see the configuration for SEO. Please select “yes” for option “Search Engine Friendly URLs”. Then apply and save your settings. Also please go to Mambo installation folder and rename htaccess.txt file to .htaccess.
Now all URLs on your site are SE-friendly. But the navigation will not work properly. It happens because Mambo uses variable $_SERVER[ ‘REQUEST_URI’ ] which is not supported by IIS.
You will need to make a little fix in the Mambo’s source code. Please copy this code to clipboard:
if ( isset( $_SERVER[ 'HTTP_X_REWRITE_URL' ] ) ) { $_SERVER[ 'REQUEST_URI' ] = $_SERVER['HTTP_X_REWRITE_URL' ]; }
Now you need to find index.php file in the root of Mambo installation folder. Please open this document with any editor and paste the above code at the top of index.php as shown on this picture:
Done! Now you can use Mambo CMS with pretty SE-friendly URLs. This article describes how to use Mambo with its default rules in .htaccess file, but of course you may replace them.
]]>You can download Joomla from official web site: http://joomla.org/download.html. After downloading please install Joomla according to installation instructions provided by vendor.
By default SE-friendly URLs are disabled. To enable this feature please go to the administration panel of Joomla. On the main page of administration panel please select “Global Configuration”

On the opened page you can see the group-box called “SEO Settings”. Please select “yes” for options “Search Engine Friendly URLs” and “Use Apache mod_rewrite”. Then apply and save your settings. Also please go to Joomla installation folder and rename htaccess.txt file to .htaccess.

Now all URLs on your site are SE-friendly. But there are some hurdles left. When you type different URLs in the address bar you always end up with the main page. It happens because Joomla uses variable $_SERVER[ ‘REQUEST_URI’ ] which is not supported by IIS.
You will need to add a little fix in the Joomla’s source code. Please copy this code to clipboard:
if ( isset( $_SERVER[ 'HTTP_X_REWRITE_URL' ] ) ) { $_SERVER[ 'REQUEST_URI' ] = $_SERVER['HTTP_X_REWRITE_URL' ]; }
Now you need to find index.php file in the root of Joomla installation folder. Open this document with any editor supporting Unix format (e.g. WordPad). Note: you can’t use Notepad to edit index.php because Notepad does not support saving in Unix format. Paste code above at the top of index.php as shown on this picture:

Done! Now you can use Joomla CMS with pretty SE-friendly URLs. This article describes how to use Joomla with its default rules in .htaccess file but of course you may replace them.
]]>
In the simplest case there are only two request processing contexts:
Server context is executed first and after that, if further processing is allowed (no redirect or proxy happened), root folder config is processed (if present).
![]()
Picture 1. Server-wide configuration (httpd.conf)
![]()
Picture 2. Per-site configuration (.htaccess)
![]()
Picture 3. Processing order for the configs on Pictures 1 and 2
***
Now let’s make it more complicated—we’ll have the rules in the root folder and in Directory1. The processing order then becomes:
DirectiveA
DirectiveB
![]()
Picture 4. Processing order in case of several .htaccess files
For the request to http://localhost/index.html only the first context is applied, while for http://localhost/Directory1/index.html (and other requests to deeper subfolders) the merged context 1+2 is executed. In our case it’s:
DirectiveA
DirectiveB
Thus, the child context complements and refines the parent one (but not the server one). This is true for nearly all Apache/Ape modules EXCEPT mod_rewrite. It’s one of a kind and behaves differently.
Historically, or for convenience purposes, mod_rewrite contexts do not complement but COMPLETELY OVERRIDE each other. So, if we have two configs
RewriteRule a b
RewriteRule b с
the resulting config to be applied to the request will be
RewriteRule b c
and NOT
RewriteRule a b
RewriteRule b с
which may be unobvious for newbies.
For experts! mod_rewrite has an option allowing to change this behavior and inherit the parent rules:
- /.htaccess
RewriteRule a b- /Directory1/.htaccess
# inherit parent rules RewriteOptions inherit RewriteRule b сmakes up the following merged config:
RewriteRule b с # parent rules are appended to the end of the merged config! RewriteRule a b
<Directory> section is equivalent in meaning to writing rules in the .htaccess located inside this directory. The only difference is that <Directory> lives in httpd.conf.
If there are both <Directory> section and .htaccess for the same directory, they are merged; if the directives inside them interfere, the .htaccess directives are preferred.
![]()
Picture 5. Processing order when there are both .htaccess and <Directory> for the same location
Let’s see how the configs are merged for the request to http://localhost/Directory1/Directory2/index.html if each directory has both <Directory> section and corresponding .htaccess file.
![]()
Picture 6. Processing order when there are several .htaccess files and several <Directory> sections which are applicable for the same request
httpd.conf
<Directory C:/inetpub/wwwroot/>
DirectiveDirectoryA
</Directory>
<Directory C:/inetpub/wwwroot/Directory1/>
DirectiveDirectoryB
</Directory>
<Directory C:/inetpub/wwwroot/Directory1/Directory2/>
DirectiveDirectoryС
</Directory>
/.htaccess
DirectiveA
/Directory1/.htaccess
DirectiveB
/Directory1/Directory2/.htaccess
DirectiveC
The following logics is applied to form the merged config:
The resulting sequence of directives will be:
DirectiveDirectoryA
DirectiveA
DirectiveDirectoryB
DirectiveB
DirectiveDirectoryC
DirectiveC
Usually directives’ order is not so important, but not in case with mod_rewrite; that’s why understanding the principles of configs merging may dramatically reduce development and debugging times.
Note! <DirectoryMatch> sections are applied not to all parts of the request (see above) but only to the deepest part, and all matches are searched for, for example, if there are two sections:
<DirectoryMatch C:/inetpub/wwwroot/Directory1/Directory*/>and
<DirectoryMatch C:/inetpub/wwwroot/Directory1/*/>then both of them get into the merged config.
One should remember that everything written inside server context is applied to all requests and for all sites. Sometimes it may be necessary to limit the scope of directive to one or several sites and that’s the case to use <VirtualHost> section.
<VirtualHost> can reside in httpd.conf only. It is merged with server config, i.e. complements it. In case of both .htaccess and <VirtualHost> section for the specific location, the latter has higher priority and can reject server settings for the specific site (in our case localhost).
#httpd.conf
ServerDirective
<VirtualHost localhost>
VirtualHostDirectiveA
</VirtualHost>
Note! mod_rewrite offers another way to restrict scope for the rules to specific host – RewriteCond %{HTTP_HOST}.
The difference is that RewriteCond %{HTTP_HOST} must appear before each RewriteRule, while <VirtualHost localhost> groups all rules for localhost together and affects all of them. Compare:
RewriteCond %{HTTP_HOST} localhost
RewriteRule . index.php [L]
RewriteCond %{HTTP_HOST} localhost
RewriteRule about$ about.php [L]
and
<VirtualHost localhost>
RewriteRule . index.php [L]
RewriteRule about$ about.php [L]
</VirtualHost>
On the other hand, the limitation of <VirtualHost> is that it can’t be used in .htaccess.
![]()
Picture 7. Processing order when <VirtualHost> section is present in httpd.conf
Note! <VirtualHost> sections are NOT merged together – if there are several <VirtualHost>s matching the request, the one with the best match is applied. E.g.:
<VirtualHost localhost> <VirtualHost localhost:80> <VirtualHost *>For request to localhost:80/page.html the second line will be executed, whereas for localhost/page.html the first one will fire.
If <Directory> section is specified inside <VirtualHost> (which is possible), the processing order is as follows: <Directory> section of the main server config is accounted first, then <Directory> inside <VirtualHost> and after all – .htaccess.
Thus, the use of <Directory> section outside <VirtualHost> will lead to application of its (<Directory>) rules to all sites (in case they use this shared folder).
![]()
Picture 8. Processing order when there are <VirtualHost> and <Directory> sections as well as .htaccess
These two behave similar to <DirectoryMatch> but are used for file names, not for the full path.
E.g., for http://localhost/Directory1/index.html#top they will find the correspondence in file system C:\inetpub\wwwroot\Directory1\index.html and will merge all <FilesMatch> sections valid for this file name (e.g. <FilesMatch *.html> and <FilesMatch index.*> will be merged).
Note! <Files> and <FilesMatch> may reside in .htaccess as well!
Are applied to the corresponding virtual path, which for http://localhost/Directory1/index.html#top is /Directory1/index.html.
Let’s now put it all together. Here’s the final sequence of sections:
***
Seems every aspect of configs processing has been covered. We understand that this article may look somewhat sophisticated, but we are sure there are enthusiasts who’ll find it helpful.
ISAPI_Rewrite in its turn is far more complex tool – you need to be aware of (at least) the basics of regular expressions to manage it. Most of the configuration is stored in plain text files which may be edited in a special manager.
RewriteEngine on
RewriteBase /
RewriteCond %{QUERY_STRING} ^param_id=(\d+)$
RewriteRule ^real_page\.aspx$ seo_page-%1.html? [NC,R=301,L]
RewriteRule ^seo_page-(\d+)$ real_page.aspx?param_id=$1 [NC,L]
So, the key difference is that LinkFreeze changes links on pages and ISAPI_Rewrite doesn’t!
If you are the lucky user of IIS7 (7.5) and need ISAPI_Rewrite/LinkFreeze capabilities, you can benefit from using Helicon Ape tool which includes mod_rewrite and mod_linkfreeze as well as a bunch of other helpful modules and functions.
Hope this article favored better understanding of the products capabilities and peculiarities, and you choice will be more conscious.
Best regards,
Anton, Helicon Tech
In ISAPI_Rewrite 3.1.0.70 and Ape 3.0.0.32 one can have more than 9 submatches and consequently more than 9 back-references in both RewriteCond and RewriteRule (RewriteProxy, RewriteHeader) statements.
The syntax to address these submatches is illustrated in the following example:
RewriteBase /
RewriteCond %{QUERY_STRING} ^id1=(\d+)&id2=(\d+)&...&id10=(\d+)&id11=(\d+)$
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)...
.../([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/$
%1/%2/%3/%4/%5/%6/%7/%8/%9/%%10/%%11?id1=$1&id2=$2&...&id10=$$10&id11=$$11 [L]
Note! This syntax is not supported in Apache.
Note! We highly recommend to avoid rules like that (as they indicate your URLs are not really SEO-friendly), but if there’s no other way out, do use it.
We believe this small bit of functionality will save you time and efforts.
Best regards,
Anton, Helicon Tech Team