Jump to content

Manual:Wiki family

From mediawiki.org

This page should lead you through the installation and configuration of a small wiki-family.

Scenario 1: Using Virtual Directories with shared-hosting provider to Display Multiple Wikis

This approach takes advantage of symlinks on a Unix-based system. This technique can also be used on Windows systems by installing a program providing symbolic links.

How to use "virtual directories" to operate more than one wiki on a single server, using the same source code (i.e. single set of MediaWiki files), using the same database, on a Unix-based system on a shared host:

See the solution, including step-by-step, detailed instructions: http://www.steverumberg.com/wiki/index.php/WikiHelp.

Note that using a language subdomain similar to Wikipedia (en.example.com, fr.example.com and so on) will allow you to produce the capabilities of the above link's Method 2 while providing a simple differentiation of the two wikis through the use of a web server's virtual host capability.

Scenario 2: Passing a Parameter to Index.php to Display Multiple Wikis

How to display different wikis by simply passing a parameter to the index.php file. Allows you to operate more than one wiki on a single server, using the same source code (i.e. single set of MediaWiki files), using the same database, on any system, including a shared host:

See the solution, including step-by-step, detailed instructions: http://www.steverumberg.com/wiki/index.php/WikiHelp

Inspired in part by Scenario 3, below.

Scenario 3: Quick set-up

You want to install more than one wiki on a single server, using the same source code (i.e. single set of MediaWiki files) , and using the same database?

  1. Install prerequisites.
  2. Upload MediaWiki files to web folder on the webserver.
  3. From browser, browse to the uploaded folder (for example, if your web server is running as http://localhost and MediaWiki files were uploaded to /testwiki/ folder, then the URL would be http://localhost/testwiki) which will lead to a page which gives a link to Please set up the wiki first. Click the link, fill-in the setup form, and install the first wiki (e.g., MyWiki). For details, see Manual:Config script.
  4. After successful installation, move LocalSettings.php into the root directory of your wiki and rename it in such a way to make it easy to track (e.g., myWikiLocalSettings.php)
  5. Repeat step three and four above for each wiki you wish to create, creating a new LocalSettings.php file for each wiki (e.g., anotherWikiLocalSettings.php, etc.)
  6. If two or more separately installed wikis are to be merged to operate out of files of the main wiki , then after renaming and moving each of your LocalSettings.php files to the main wiki folder, change the variable $wgScriptPath in the each of the LocalSettings.php files to point to the main wiki's folder.
  7. Create a LocalSettings.php file for your global settings, then select one from the two possibilities below:
1: If you have different domains/subdomains that link to one directory on your server, use this:
Note Note:To link your subdomains to one directory on your server, you may have to edit the configuration file for your server (can not be done with a .htaccess file, try changing httpd-vhosts.txt there in Apache web server setup) or, if your site has its own IP address, modify the DNS configuration for your site.
<?php
	switch ($_SERVER["SERVER_NAME"])
	{
		case "shoopz.com":
			require_once "LocalSettings_shoopz_com_.php";
			break;

		case "help.shoopz.com":
			require_once "LocalSettings_help_shoopz_com_.php";
			break;

		case "wiki.shoopz.net":
			require_once "LocalSettings_wiki_shoopz_net.php";
			break;

		default:
			echo "This wiki is not available. Check configuration.";
			exit(0);
	}
?>


OR 2: If your wikis are in different directories (e.g. yourdomain.com/wiki1, yourdomain.com/wiki2 etc) linked to the main wiki directory on your server (say yourdomain.com/w), use this:
Note Note: If the function strpos() finds the string you search for at the beginning of $callingurl, then the function returns 0 (i.e. it found the string starting at position zero) therefore, you need to change if(strpos($callingurl,'wikiN')) to if(strpos($callingurl,'wikiN') !== FALSE).
<?php

$callingurl = strtolower($_SERVER['REQUEST_URI']); //get the calling url

if ( strpos( $callingurl, 'wiki1', 0) ) {
        require_once( 'LocalSettings_wiki1.php' );
}
else if ( strpos( $callingurl, 'wiki2', 0) ) {
        require_once( 'LocalSettings_wiki2.php' );
}
.
.
.
else if ( strpos( $callingurl, 'wikiN', 0) ) {
        require_once( 'LocalSettings_wikiN.php' );
}
else {
        echo "This wiki (in ". $callingurl . ") is not available. Check configuration.";
        exit(0);
}
Note Note: If you use Short URL with the second case (directory based wikis), you need to check the two directories: strpos( $callingurl, 'wiki1', 0) || strpos( $callingurl, 'w1/', 0), to symlink the sources (w1 -> w), and adapt $wgScriptPath.
Note Note: You should use "srtpos() == 1" or similar instead of plain strpos() to avoid redirecting to wrong wiki when the url contains the name after the beginning

You can use a different unique MySQL database for each wiki (see $wgDBname) OR you can use a different table prefix for each wiki (for Postgres, you can achieve a similar effect by using different schemas) (see $wgDBprefix).

Scenario 4: Drupal-style sites

As above, this setup allows you to install more than one wiki on a single server, using the same source code. This setup has the advantage of being completely transparent to users and reasonably secure in terms of the images directory.

  • Create a base directory to contain all your MediaWiki files e.g., mkdir /home/web/mediawiki.
  • Install MediaWiki and additional tools as usual to a version-declaring subdirectory(e.g., /home/web/mediawiki/mediawiki-1.10.0).
  • Link the version-declaring directory to a code directory. e.g., ln -s /home/web/mediawiki/mediawiki-1.10.0 /home/web/mediawiki/code
  • Create a sites directory to contain our images and settings: mkdir /home/web/mediawiki/sites
  • Setup the wiki as normal from the /code directory.
  • After successful installation, move LocalSettings.php into a sites directory that will be a match when the site is checked. For example, to capture http://mysite.com/mywiki, one would create the directory mysite.com.mywiki. e.g., mkdir /home/web/mediawiki/sites/mysite.com.mywiki. See the Drupal's settings.php file for more information on this.
  • If you intend to use media files, create an images directory in your site directory. e.g., mkdir /home/web/mediawiki/sites/mysite.com.wiki/images. Make it writable as necessary.
  • Place the Drupal-style LocalSettings.php file in your main directory: cp DrupalLocalSettings.php /home/web/mediawiki/code/LocalSettings.php
  • Modify your LocalSettings.php to point to the right places. The following modifications deserve special attention:
$IP = "/home/web/mediawiki/code";
$IPplus = "/home/web/mediawiki/sites/wiki.mysite.com";
$wgUploadDirectory  = "$IPplus/images";
  • Prepare your Apache 2 installation. Example site: wiki.mysite.com
    • ln -s /home/web/mediawiki/code /home/web/wiki.mysite.com
    • Create an appropriate VHost configuration:
<VirtualHost *:80>
    ServerAdmin me@myserver.com
    DocumentRoot /home/web/wiki.mysite.com
    ServerName wiki.mysite.com
    CustomLog /var/log/apache2/wiki.mysite.log common
    # Alias for Wiki so images work
      Alias /images /home/web/mediawiki/sites/wiki.mysite.com/images
    # If you want to password protect your site
    #  <Directory /home/web/wiki.mysite.com>
    #    AuthType Basic
    #    AuthName "My protected Wiki"
    #    AuthUserFile /etc/apache2/htpasswd/users-mywiki
    #   require valid-user
    #  </Directory>
</VirtualHost>


The site should now work. In my case, I made another copy of the code from which to install and update my LocalSettings.php and databases.

Scenario 5: Multiple wikis sharing common resources

You want to have some wikis in different languages, sharing the same media-files in another, single wiki.

For example:

  • en.yourwiki.org - English language
  • fr.yourwiki.org - French language
  • de.yourwiki.org - German language
  • pool.yourwiki.org - media-files for all of these wikis (like Commons).
    • As there is already an Interwikilink named commons for Wikimedia Commons, we name our media-files-wiki "pool".
    • Think before being creative; if you call your media-files-wiki something like "media" (e.g. media.example.com), it might collide with internal namespaces and nomenclature for embedded media files ([[media:file.ext]]).

On your filesystem, create a folder for each wiki. Run the install script for each wiki.

(This solution duplicates source code. You may wish to replace the include, skin, language and extension directories for non-pool installations with symbolic links to the pool's directories [rm -r include && ln -s pooldir/include etc.] to improve cache performance.)

Configure

Now you have to set Interwikilinks between all wikis, by editing their MySQL-Databases (if you prefer, install and use Extension:Interwiki)

  • Table Interwiki
    • iw_prefix - enter the language-code of the wikis, "de" for German, "en" for English, "fr" for French and "pool" for the mediapoolwiki
    • iw_url - this is the place for the complete URL to the wikis, e.g. "http://de.yourwiki.org/index.php/$1" for the German wiki (don't forget the "$1" !).

Now you can link an article to the same in another languages. Adding [[de:Hauptseite]] on your English Main_Page will create a link "Deutsch" (under the Navigation bar) which leads to the Main_Page of the German wiki (Hauptseite). For further information visit Help:Interwiki linking

Upload

Make sure that folder "images" of the pool-wiki is writable.

It is useful to change the "Upload file"-Link of the language-wikis to point to poolwiki's upload-site. Open the "LocalSettings.php" of each language-wiki and add:

$wgUploadNavigationUrl = "http://pool.yourwiki.org/index.php/Special:Upload";

Use shared files

To use poolwiki's files in the languagewikis, open "LocalSettings.php" for each languagewiki and add:

$wgUseSharedUploads = true;
$wgSharedUploadPath = 'http://pool.yourwiki.org/images';
$wgSharedUploadDirectory = '/(LOCALPATH)/POOL-FOLDER/images/';
$wgHashedSharedUploadDirectory = true;

Now you can integrate pool's files with (e.g.) [[Image:MyLogo.png]] in the languagewikis.

Image description

In each languagewiki, open (as an admin) the message MediaWiki:Sharedupload.

Change the text to something like:

This file is stored in our data-pool. For information and description, please visit the  

[[:pool:Image:{{PAGENAME}}|description there]]. 

(And note the ':' at the beginning of the line, which stops 'pool' from being included in the interwiki list at the left of the page.)

If you want to output the media-description, stored in the PoolWiki, too, add to the "LocalSettings.php" of the languagewikis:

$wgFetchCommonsDescriptions = true;
$wgSharedUploadDBname = 'pool';  # DB-Name of PoolWiki
$wgSharedUploadDBprefix = 'wiki_'; # Table name prefix for PoolWiki
$wgRepositoryBaseUrl = "http://pool.yourwiki.org/index.php/Image:";

Shared Settings

If you have multiple wikis, you'll probably want to share similar settings across them all. Here is how to do that. We recommend that you separate your Extension settings into a different file than your other settings, as detailed below. They can be all put into one large file, but it's not as flexible depending upon your specific needs.

Here is an example directory structure if you do all of the following:

en/
es/
pl/
ja/
pool/
ExtensionSettings.php
WikiFamilySettings.php
SharedMediaSettings.php
Extension Settings
  • Step 1
    Create a file called ExtensionSettings.php with the following contents, and place it in a location similar to the example above.
<?php
#####
##### Extension Directory Variables
#####
##
## These variables allow you to specify a single, shared directory for each grouping of extensions.
## If the directory ever needs to be changed, it can be changed here rather than on every
## item below. DO NOT include a trailing "/".
##
## Extensions from svn.wikimedia.org
# $wgWikimediaExtensions = "/var/www/wikimediaextensions";
##
## Any third-party extensions
# $wgOtherExtensions = "/var/www/extensions";
#####
#####

### Add globalized extension settings below
#require_once( "$wgWikimediaExtensions/ReallyCoolExtension/ReallyCoolExtension.php" ); #An example Wikimedia Subversion extension entry

#require_once( "$wgOtherExtensions/ReallyCoolExtension/ReallyCoolExtension.php" ); #An example third-party extension entry
  • Step 2
    Edit the LocalSettings.php file of each wiki that you want to use the shared settings, and add the following.
require_once( "/absolute/path/to/ExtensionSettings.php" );
  • Step 3
    Now just add all the references to your various extensions
Wiki Family Settings

These are settings that you want to apply to the entire wiki family. For example, maybe you want to be able to easily put all the wikis into read-only mode at the same time. You can also store the username/password for the database(s), if they are all the same. Additionally, you could control user permissions across your entire wiki from this one file.

Note: If you use a Images/Media commons or pool, we recommend that you not put these settings in the WikiFamilySettings.php file. That information only applies to every wiki in your wiki family other than your repository. We recommend putting it in a separate file.

Scenario 6: Multiple wikis through RewriteRules

This approach is based on the work of Mizanur Rahman (see Boolean Dreams Article and it has elements in common with #Scenario 3: Quick set-up above. Follow steps 1-5 in #Scenario 3: Quick set-up to setup the individual wikis. Then modify the LocalSettings.php file for each wiki along the lines:

Wiki 1 Local Settings File:

$wgArticlePath = "/wiki1/$1"; // Gives us Wikipedia style urls for articles.
$wgScriptPath =  "/srcwiki1"; // Makes non-article urls unique for this wiki.

Similarly for Wiki 2 Local Settings File:

$wgArticlePath = "/wiki2/$1"; // Gives us Wikipedia style urls for articles.
$wgScriptPath =  "/srcwiki2"; // Makes non-article urls unique for this wiki.

You'll also need a master file, along the lines described in step 7 of #Scenario 3: Quick set-up to choose the appropriate local settings file for wiki1 or wiki2 based on a url.

Finally, in the .htaccess file you need RewriteRules to map the article urls to standard wiki urls and non-article urls to the folder containing the wiki source. Assuming the wiki source is installed in '/w/', .htaccess would be something like:

RewriteEngine On
RewriteRule ^wiki1/(.*)$ /w/index.php?title=$1 [PT,L,QSA]
RewriteRule ^wiki1/*$ wiki1/ [L,QSA]

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

RewriteRule ^srcwiki1/(.*)$ /w/$1 [PT,L,QSA]
RewriteRule ^srcwiki2/(.*)$ /w/$1 [PT,L,QSA]

Fix for Maintenance Scripts

Maintenance scripts run directly, not via a url so the RewriteRules won't provide a suitable url for the master LocalSettings.php file to $_SERVER["SERVER_NAME"] or $_SERVER['REQUEST_URI']. To work around this, use a separate global varible to offer an alternate selection method and define the variable on the command line when calling maintenance scripts. A suitable master LocalSettings.php would be something like:

<?php
if (isset($gWikiSelect))
{
  if ($gWikiSelect == 'wiki1')
  {
    require_once('Local_Wiki1_Settings.php');
    require_once('Admin_Wiki1_Settings.php');
    
  } else if ($gWikiSelect == 'wiki2')
  {
    require_once('Local_Wiki2_Settings.php');
    require_once('Admin_Wiki2_Settings.php');
  } 

} else
{ 
  $callingUrl = strtolower($_SERVER['REQUEST_URI']);

  if (strpos($callingUrl, wiki1))
  {
    require_once('Local_Wiki1_Settings.php');
    
  } else if (strpos($callingUrl, 'wiki2'))
  {
    require_once('Local_Wiki2_Settings.php');
  } 
}
?>

Then, when running a maintenance script, such as importImages.php from the command line:

php -d auto_prepend_file=SelectWiki1.php importImages.php c:\myimages

Here the -d switch modifies the auto_prepend_file setting in php.ini to execute a file before the importImages.php script. This file sets the global variable to select the wiki:

<?php
$gWikiSelect='wiki1';
?>

Ultimate minimalist solution

The ultimate minimalist solution consists of symlinks,

$ ls -og
lrwxrwxrwx 1 16 2008-11-03 06:29 aaa.example.org -> mediawiki-2.3.4
lrwxrwxrwx 1 16 2008-11-03 06:29 bbb.example.org -> mediawiki-2.3.4
lrwxrwxrwx 1 16 2008-11-03 06:29 ccc.example.org -> mediawiki-2.3.4

And in the heart of mediawiki/LocalSettings.php:

$sites=array('aaa','bbb','ccc');
foreach($sites as $v){
  if(strpos($_SERVER['SCRIPT_FILENAME'].$_SERVER['PWD'],$v)){
    $wgDBname=$v; break;}}
$wgLogo="/skins/common/images/$wgDBname.png"; $wgSitename=$wgDBname; #$wgFavicon=...

Note we still individually do database related tasks, e.g., cd aaa.example.org/maintenance && php update.php . (Occasionally there are places where something writing to disk assumes there is only one wiki: Bugzilla:11654.)

Real life example

In real life, the naming part is probably more customized, e.g.,

foreach (array('radioscanningtw'=>'台掃','taizhongbus'=>'中公','transgender'=>'蝶園','IMPOSSIBLE'=>0)
    as $wgDBname=>$wgSitename){if(strpos($_SERVER['SCRIPT_FILENAME'].$_SERVER['PWD'],$wgDBname)){break;}}
if(!$wgSitename){trigger_error('請通知我網站又壞了:積丹尼(04)25854780',E_USER_ERROR);}

Here the administrator even adds a message to telephone him if the script breaks.

Upgrading

We might use a script like:

#Usage: $ ./this_script mediawiki-1.13.4 mediawiki-1.14.1 stage #=0..4
set -uxe; test $# = 3; s='aaa bbb ccc'; images= sites=
for i in $s
do images=$images\ skins/common/images/$i.png; sites=$sites\ $i.example.org; done
case $3 in
    0)	v=$2; v=${v#*-}; v=${v%.*}
	wget -nc http://download.wikimedia.org/mediawiki/$v/$2.tar.gz
        tar zxf $2.tar.gz;;
    1)	for i in LocalSettings.php AdminSettings.php $images
	do ln $1/$i $2/$i; done;;
    2)	for i in $sites; do rm $i; ln -s $2 $i; done;;
    3)  for i in $sites; do cd $i/maintenance; php update.php; cd -; done;;
    4)  rm -r $1 $2.tar.gz;;
esac

Images

Unless you do not allow uploads or allow them only for your pool wiki, you will need to create separate image directories and alias them in your vhost configuration: for i in aaa bbb ccc; do mkdir -p /home/user/images/$i; done, and in aaa.example.org's vhost: Alias /w/images /home/user/images/aaa. Same for bbb and ccc.

However you may instead just prefer Manual:Image Administration#Alternative simple setup, where *.example.org/images/ just point to the same single directory.

Wiki Farmer Extension

see Extension:Farmer

Wikimedia Method

Another option is using the method that the Wikimedia Foundation uses. The rough steps are listed below. This method isn't for the faint of heart, but it has fairly good results, as can be seen by the success the Wikimedia Foundation has had by using this :-)

  1. Configure a template copy of MediaWiki through the online configuration wizard. Edit the Main Page if you want a default main page for every wiki you create on your farm.
  2. After that, export your database with mysqldump, phpMyAdmin, etc. Save this on your server in the maintenance/ directory as something like template.sql.
  3. Now, write up a few quick scripts to create a new wiki. In a gist, you'll need to add it to a list of wikis, which can be flat-file based or MySQL/SQLite based, and then import the template database dump back into the database under the name of a new wiki. Use a standard suffix after the new database name (i.e. if the wiki is meta.yourdomain.net, then you might choose metawiki as the database name).
  4. In your configuration file, add something like this, fixing the database prefix and your domain as necessary:
    if ( preg_match( '/^(.*)\.yourdomain.net$/', $server, $matches ) ) {
         $wikiname = $matches[1];
    } else {
         die( "Invalid host name, can't determine wiki name" );
         // You could also redirect to a nicer "No such wiki" page.
    }
    
    if( $wikiname == "www" ) {
         // Change this to your "main" wiki.
         $wikiname = "meta";
    }
    
    $wgDBname = $wikiname . "wiki";
    
  5. Configure your DNS with a wildcard A record, and apache with a server alias (like ServerAlias *.yourdomain.net) and you should be in business.

You'll probably want to fix some scripts like maintenance/update.php so that you can specify a database name as a command line argument. You'll also need to fix the upload directories unless you want every wiki to use the same files. As said above, this is probably one of the hardest methods to do, and it requires more technical experience, but it can give really good, clean results.