Eliminating index.php from the url

From Meta, a Wikimedia project coordination wiki
This is an archived version of this page, as edited by 158.250.19.37 (talk) at 14:27, 15 June 2005 (→‎Using a rewrite rule in a .htaccess file: Should use backslash here, otherwise regexp won't match any URL (URL always starts with backslash)). It may differ significantly from the current version.

<- MediaWiki User's Guide

The biggest mistake that many people make is to try and give articles urls like http://www.mysite.com/articlename . The trouble with doing this is that you need to have things other than articles within your site and you have just filled your entire namespace with articles so you have nowhere to put them. This is why wikimedia sites use articles of the form http://www.mysite.com/wiki/articlename leaving the rest of the site's namespace for other things. Whilst it is possible to set up a site with urls like http://www.mysite.com/articlename it is a very bad idea to do so (read the old content section on this page if you are really interested in doing so and note how much cruft there is for getting round the pitfalls)

Getting URLs like those on WikiMedia sites

This method will put articles under www.mysite.com/wiki/articlename, and everything else under www.mysite.com/w/index.php?whatever, just like the WikiMedia sites.

Replace www.mysite.com and /filesystem/path/to/my/site to suit your site, of course.

Using an alias in httpd.conf

This is the prefered method from a performance point of view, but requires access to edit httpd.conf; unfortunately, this is unlikely in a shared hosting environment.

  1. install mediawiki in the dir for www.mysite.com/w as normal (using the installer)
  2. set $wgArticlePath = "/wiki/$1"; in LocalSettings.php
  3. add aliases like the following to httpd.conf (if you are using apache virtual hosting you will want to put it inside the <virtualhost>)
Alias /wiki/skins     /filesystem/path/to/my/site/w/skins
Alias /wiki           /filesystem/path/to/my/site/w/index.php

Using a rewrite rule in a .htaccess file

This method may be useful if you have the ability to use rewrite rules in .htaccess and don't have conf access but it is more work for the httpd.

  1. install mediawiki in the dir for www.mysite.com/w as normal (using the installer)
  2. set $wgArticlePath = "/wiki/$1"; in LocalSettings.php
  3. put a htaccess file with the following content in the dir for www.mysite.com
# close the php security hole... 
#  not actually needed but probablly a good idea anyway
php_flag register_globals off

# first, enable the processing - Unless your ISP has it enabled
# already.  That might cause weird errors.
RewriteEngine on

# uncomment this rule if you want Apache to redirect from www.mysite.com/ to www.mysite.com/wiki/Main_Page
# RewriteRule ^$ /wiki/Main_Page [R] 

# do the rewrite
RewriteRule ^/wiki/?(.*)$ /w/index.php?title=$1 [L,QSA]

Further notes

If you notice that your changes to $wgArticlePath in LocalSettings.php are not being reflected in mysite.com/wiki/Main_Page, it may be due MediaWiki's caching of the links according to previous settings. Goto mysite.com/wiki/Main_Page?action=purge to force MediaWiki to regenerate the cached links.

If you didn't follow the instructions and installed MediaWiki in the directory for www.mysite.com/wiki, then you will need to do something to prevent Apache from getting into rewrite loops. There are a couple of possibilities for doing this.

One option is to only rewrite for article names beggining with a capital letter using the rule below instead of the second rule in the main instructions. However this will mean that your users have to type the capital letters when visiting your pages which is annoying.

# Only rewrite words starting with a uppercase letter (Word, not word)
# Don't rewrite stupid work like "_()_"
RewriteRule ^wiki/([A-Z][A-Za-z0-9:_-]*)$ wiki/index.php?title=$1 [L,QSA]

another way is to add special cases like the following:

# I don't know why I need to add this, Apache should not
# rewrite the url twice ! But it doesn't work without it
RewriteRule ^wiki/index.php$ wiki/index.php [L,QSA]

# Only rewrite words (like wiki/Word), not subdirectories (like wiki/skins/...)
RewriteRule ^wiki/([^\/]+)$ wiki/index.php?title=$1 [L,QSA]

Another way, without mod_rewrite

note: this section was written by an anon and i have not yet had chance to test it Plugwash 01:54, 29 May 2005 (UTC)[reply]

Change your .htaccess :
DirectoryIndex wiki
php_flag register_globals off
<Files "wiki">
ForceType application/x-httpd-php
Allow from all
</Files>
<Files "wikiredirect">
ForceType application/x-httpd-php
Allow from all
</Files>
Make the wiki file (without extension, at the rootpath):
<?php include_once('index.php');?>
Make the wikiredirect file (without extension, at the rootpath):
<?php include_once('redirect.php');?>

This solution may be faster than mod_rewrite

See Also

See the talk page for more information upon setting up non root rewrite rules.

Troubleshooting

If you get internal server errors or similar, check out the Apache error.log. This usually has some clues about the reasons.

See also

Next page: PHP config >

Old info

There are undoubtably some gems in this section but there is also a load of overcomplicated stuff. Follow this advice only with due consideration and caution take everything from here downward with a bucketload of salt.

---

Note: You must also configure your LocalSettings.php or your wiki will run extremely slowly.

If you want to be able to access articles with http://wiki.domain.tld/article name instead of http://wiki.domain.tld/index.php?title=article_name and you have an Apache-based server where you'll be able to access index.php using http://wiki.domain.tld/index.php, you can use the following configuration (this is for release 1.2, see these older rules otherwise). If used in an .htaccess file, the apache needs to be configured to allow the use of rewrite rules from .htaccess, a 403 (not allowed) error is the result otherwise. .htaccess is not recommended however - so please use httpd.conf (.htaccess does work sometimes, but can be quite tricky to set up).

Note: This won't work for article names that are the same as MediaWiki php filenames or that start with "stylesheets/" or "images/".

LocalSettings.php

Use the following lines in LocalSettings.php :

$wgSitename         = "My Site";
$wgServer           = "http://your.domain.tld";
$wgScriptPath       = "";
$wgScript           = "$wgScriptPath/index.php";
$wgRedirectScript   = '$wgScriptPath/redirect.php';
$wgStyleSheetPath   = '$wgScriptPath/stylesheets';
$wgUploadPath       = '$wgScriptPath/images';
$wgLogo             = "{$wgUploadPath}/wiki.png";
$wgMathPath         = "{$wgUploadPath}/math";
$wgArticlePath      = "$wgScriptPath/$1";
$wgEmergencyContact = "wikiadmin@domain.tld";

(If you are using a specific folder, i.e. not root folder, then the

$wgScriptPath       = "/wiki";

or something similar)

httpd.conf

Use the following lines in a VirtualHost container in your Apache httpd.conf or access.conf if you use it (might also work in working-directory/.htaccess) :

# Allow wiki articles to start with a period
<Files .*>
  Order Deny,Allow
  Allow From All
</Files>

# Allow rewriting URLs
RewriteEngine on

only needed for backwards compatibility

# The following rules are only for backwards compatibility 
# (so that old links to your site keep working). You should leave them out in a new install.
# Redirect old /wiki/ urls
RewriteRule ^/wiki/(.*)$ http://your.domain.tld/$1 [R,L]
# Redirect old /wiki.phtml?title= and index.php urls
RewriteRule ^/wiki\.phtml\?title=(.*)$ http://your.domain.tld/$1 [R,L]
RewriteRule ^/index.php\?title=(.*)$ http://your.domain.tld/$1 [R,L]
RewriteRule ^/index.php/(.*)$ http://your.domain.tld/$1 [R,L]
# end backward compatibility rules, the following ones are important

important ones

# Don't rewrite requests for files in MediaWiki subdirectories,
# MediaWiki PHP files, HTTP error documents, favicon.ico, or robots.txt
RewriteCond %{REQUEST_URI} !^/(stylesheets|images|skins)/
RewriteCond %{REQUEST_URI} !^/(redirect|texvc|index).php
RewriteCond %{REQUEST_URI} !^/error/(40(1|3|4)|500).html
RewriteCond %{REQUEST_URI} !^/favicon.ico
RewriteCond %{REQUEST_URI} !^/robots.txt

'/skins/ directory has been added in version 1.4.  /stylesheets/ is no longer needed but kept for backwards- compatibility.

the key rule

# Rewrite http://wiki.domain.tld/article properly, this is the main rule
RewriteRule ^/(.*)$ /index.php/$1 [L,QSA]

The above fails for titles with question marks (%3F) in them.

Meanwhile this will fail for URLs with ampersands:

RewriteRule ^/(.*)$ /index.php?title=$1 [L,QSA]

To make both work, you need to patch Apache (the patch is in the maintenance/ directory and should apply to 1.3.x; there is not a patch for 2.0.x available) and do something like this:

RewriteMap ampescape int:ampescape
RewriteRule ^/(.*)$ /index.php?title=${ampescape:$1} [L,QSA]

.htaccess

If you don't have root access to your host machine, as is typical when you buy your web hosting through a third party, then you can still rewrite your URL's using the .htaccess file. You can also turn off the register_globals flag from this file (recommended) if it is on by default for the site. Here's a working .htaccess file from a site where MediaWiki is installed into a sub-folder called wiki:

# close the php security hole...
php_flag register_globals off

# first, enable the processing - Unless your ISP has it enabled
# already.  That might cause weird errors.
RewriteEngine on

# Rewrite wiki?xxx as wiki/index.php?xxx and stop
RewriteRule ^wiki$ wiki/index.php [L]

# Don't rewrite requests for files in MediaWiki subdirectories,
# MediaWiki PHP files, HTTP error documents, favicon.ico, or robots.txt
RewriteCond %{REQUEST_URI} !^/wiki/(stylesheets|images|skins)/
RewriteCond %{REQUEST_URI} !^/wiki/(redirect|texvc|index).php
RewriteCond %{REQUEST_URI} !^/error/(40(1|3|4)|500).html
RewriteCond %{REQUEST_URI} !^/favicon.ico
RewriteCond %{REQUEST_URI} !^/robots.txt

# Rewrite any article as wiki/index.php/article and stop
RewriteRule ^(.*)$ index.php/$1 [L,QSA]

Note that if your version of Apache doesn't support the [QSA] or [qsappend] flag (for example, some versions of Ensim), simply append the query string directly:

RewriteRule ^(.*)$ wiki/index.php/$1?%{QUERY_STRING} [L]

Note that the first rule pretends that a program wiki exists but rewrites it to pass the command line to /wiki/index.php. In LocalSettings.php you can make MediaWiki use the pretend wiki program. Here are the changes to LocalSettings.php:

$wgScript           = "/wiki";
$wgArticlePath      = "/$1";

With these rules, users can access an article using:

  • http://your.domain.tld/article
  • http://your.domain.tld/wiki?title=article
  • http://your.domain.tld/wiki/index.php/article
  • http://your.domain.tld/wiki/index.php?title=article

Using aliases instead of rewrite

Rewrite is very powerful in apache, and perhaps not entirely necessary. The alias mechanism also works for at least the simpler cases above:

Alias /wiki/stylesheets /home/php/wiki/stylesheets
Alias /wiki/style /home/php/wiki/style
Alias /wiki/images /home/wiki/images
Alias /wiki/skins /home/php/wiki/skins
Alias /wiki/redirect.php /home/php/wiki/redirect.php
Alias /wiki/textvc.php /home/php/wiki/textvc.php
Alias /wiki/index.php /home/php/wiki/index.php
Alias /wiki /home/php/wiki/index.php

Note the following:

  • These are based on the wiki NOT being at the top level, but under /wiki/. (Probably removing wiki/ would work but I did not test this.)
  • If you have the wiki at the top level and have other custom subfolders or root level files you'll need to add an alias for each one (so the final alias above for /wiki does not hijack your other stuff).
  • In your LocalSettings.php you will also need to set this: $wgScript = "$wgScriptPath";
  • The aliases above are ORDERED. Shorter aliases must occur after longer ones or the longer ones will be covered.
  • This maps the URL directly to the server's internal filesystem path, short circuiting the server's URL translation.
  • The images directory is not in the php directory with the rest. (see Documentation:Security)

This could also be refactored and AliasMatch used instead.

I have tested this. It should translate something like

  http://server/wiki/Page_name

into the internal path

  /home/php/wiki/index.php/Page_name

which just magically works.


Other useful rewrites

The following magically converts /wiki/Today into a page for a real date like /wiki/March_24_2005.

# These rules convert "Today" to a date...
# Make sure the "Today" page itself also exists so it can be
# referred to in a [[ ]] link.
RewriteRule ^wiki/Today/?$ /wiki/_Rewrite_%{TIME_DAY}_%{TIME_MON}_%{TIME_YEAR}
RewriteRule ^wiki/_Rewrite_0(.*/?) /wiki/_Rewrite_$1
RewriteRule ^wiki/_Rewrite_([0-9]+)_0?1_([0-9]*)/? /wiki/January_$1_$2
RewriteRule ^wiki/_Rewrite_([0-9]+)_0?2_([0-9]*)/? /wiki/February_$1_$2
RewriteRule ^wiki/_Rewrite_([0-9]+)_0?3_([0-9]*)/? /wiki/March_$1_$2
RewriteRule ^wiki/_Rewrite_([0-9]+)_0?4_([0-9]*)/? /wiki/April_$1_$2
RewriteRule ^wiki/_Rewrite_([0-9]+)_0?5_([0-9]*)/? /wiki/May_$1_$2
RewriteRule ^wiki/_Rewrite_([0-9]+)_0?6_([0-9]*)/? /wiki/June_$1_$2
RewriteRule ^wiki/_Rewrite_([0-9]+)_0?7_([0-9]*)/? /wiki/July_$1_$2
RewriteRule ^wiki/_Rewrite_([0-9]+)_0?8_([0-9]*)/? /wiki/August_$1_$2
RewriteRule ^wiki/_Rewrite_([0-9]+)_0?9_([0-9]*)/? /wiki/September_$1_$2
RewriteRule ^wiki/_Rewrite_([0-9]+)_10_([0-9]*)/?  /wiki/October_$1_$2
RewriteRule ^wiki/_Rewrite_([0-9]+)_11_([0-9]*)/?  /wiki/November_$1_$2
RewriteRule ^wiki/_Rewrite_([0-9]+)_12_([0-9]*)/?  /wiki/December_$1_$2