MediaWiki
Useful areas for customisation are: /wiki/Special:AllMessages and Built-in system messages. You can normally just click the link from the list to edit the text.
Asynchronous snippet
From here
cd extensions/googleAnalytics cp googleAnalytics.php googleAnalytics.php.backup vim googleAnalytics.php
Enter the below text into the file and replace the UA- value below with your own.
<?php if ( !defined( 'MEDIAWIKI' ) ) { die( 'This file is a MediaWiki extension, it is not a valid entry point' ); } $wgExtensionCredits['other'][] = array( 'path' => __FILE__, 'name' => 'Google Analytics Integration', 'version' => '2.0.2', 'author' => 'Tim Laqua', 'descriptionmsg' => 'googleanalytics-desc', 'url' => 'http://www.mediawiki.org/wiki/Extension:Google_Analytics_Integration', ); $wgExtensionMessagesFiles['googleAnalytics'] = dirname(__FILE__) . '/googleAnalytics.i18n.php'; $wgHooks['BeforePageDisplay'][] = 'efGoogleAnalyticsHookText'; $wgHooks['ParserAfterTidy'][] = 'efGoogleAnalyticsASAC'; # registered account $wgGoogleAnalyticsAccount = "UA-XXXXX-X"; # to be used in case we had AdSense as well and have linked accounts, to enable tracking set this to true $wgGoogleAnalyticsAddASAC = false; $wgGoogleAnalyticsIgnoreSysops = true; $wgGoogleAnalyticsIgnoreBots = true; function efGoogleAnalyticsASAC( &$parser, &$text ) { global $wgOut, $wgGoogleAnalyticsAccount, $wgGoogleAnalyticsAddASAC; if( !empty($wgGoogleAnalyticsAccount) && $wgGoogleAnalyticsAddASAC ) { $wgOut->addScript('<script type="text/javascript">window.google_analytics_uacct = "' . $wgGoogleAnalyticsAccount . '";</script>'); } return true; } function efGoogleAnalyticsHookText( $out ) { $out->addScript( efAddGoogleAnalytics() ); return true; } function efAddGoogleAnalytics() { global $wgGoogleAnalyticsAccount, $wgGoogleAnalyticsIgnoreSysops, $wgGoogleAnalyticsIgnoreBots, $wgUser; if (!$wgUser->isAllowed('bot') || !$wgGoogleAnalyticsIgnoreBots) { if (!$wgUser->isAllowed('protect') || !$wgGoogleAnalyticsIgnoreSysops) { if ( !empty($wgGoogleAnalyticsAccount) ) { $funcOutput = <<<GASCRIPT <script type="text/javascript"> var _gaq = _gaq || []; _gaq.push(['_setAccount', '$wgGoogleAnalyticsAccount']); _gaq.push(['_trackPageview']); (function() { var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); })(); </script> GASCRIPT; } else { $funcOutput = "\n<!-- Set \$wgGoogleAnalyticsAccount to your account # provided by Google Analytics. -->"; } } else { $funcOutput = "\n<!-- Google Analytics tracking is disabled for users with 'protect' rights (I.E. sysops) -->"; } } else { $funcOutput = "\n<!-- Google Analytics tracking is disabled for bots -->"; } return $funcOutput; } ///Alias for efAddGoogleAnalytics - backwards compatibility. function addGoogleAnalytics() { return efAddGoogleAnalytics(); }
Installation
On Unix Debian based (so Ubuntu as well), do the following:
mkdir /var/www/sites/domain.co.uk cd /var/www/sites/domain.co.uk wget http://download.wikimedia.org/mediawiki/1.20/mediawiki-1.20.2.tar.gz tar xvzf mediawiki-*.tar.gz cd mediawiki-1.20.2 mv mediawiki-1.20.2/* . mv .gitreview .jshintignore .jshintrc .. apt-get install mysql-server build-essential apt-get install php5-mysql php-pear php5-dev php5-gd php5-imagick php5-intl libcurl3-openssl-dev libicu-dev gobjc++ pecl install intl apt-get install memcached libmemcached-dev php-auth php-mail php-mail-mime pecl install Memcache pear install net_smtp vim /etc/php5/apache2/php.ini # you need Apache installed first) # as well as vim /etc/php5/cli/php.ini /Dynamic
Add in the following lines:
extension=intl.so extension=memcache.so memcache.hash_strategy="consistent"
Choose a caching software between APC and xcache. If you want APC, use this. If you want xcache, do:
apt-get install php5-xcache memcached -u root -d -m 2048 -l 10.0.0.40 -p 11211 /etc/init.d/apache2 restart
cd /var/www/sites chown root:root domain.co.uk/ -R cd /var/www/sites/domain.co.uk chmod 700 LocalSettings.php apt-get install qmail
It will state:
qmail will refuse to accept SMTP messages except to `hostname`. Make sure to change rcpthosts if you add hosts to locals or virtualdomains!
Then check this: http://www.mediawiki.org/wiki/Manual:Config_script
And go to domain.co.uk/index.php and run through the configuration. Then download the LocalSettings.php file.
http://www.mediawiki.org/wiki/Manual:Securing_database_passwords
Account confirmation
http://www.mediawiki.org/wiki/Extension:ConfirmAccount
Upload the .tar.gz to /var/www/sites/domain.co.uk/extensions
tar -xzf ConfirmAccount.tar.gz
vim LocalSettings.php
require_once("$IP/extensions/ConfirmAccount/ConfirmAccount.php");
Exit the file and run php maintenance/update.php
To turn off "Your biography must be at least 50 words long.", as this does not use $wgAccountRequestMinWords any more:
vim /var/www/sites/domain.co.uk/extensions/ConfirmAccount/ConfirmAccount.config.php
Edit:
'Biography' => array( 'enabled' => true, 'minWords' => 50 ),
If you get the below error when approving an account:
Could not create directory "mwstore://accountcreds-backend/accountcreds-public/1/12/123".
chown www-data:www-data images/ -R chmod 755 images/ -R
Also check your "$wgFileExtensions = {'gif', 'png');" entry
You may need to create an array, something like this:
$wgFileExtensions = array('gif','png');
Capitalise headers and tab titles
vim domain.co.uk/skins/monobook/main.css
.portlet h5 { background: transparent; padding: 0 1em 0 .5em; display: inline; height: 1em; /* text-transform: lowercase; /* force text to lowercase */ /* text-transform: uppercase; /* force text to uppercase */ text-transform: capitalize; /* force text to proper case */ font-size: 91%; font-weight: normal; white-space: nowrap; } .portlet h6 { background: #ffae2e; border: 1px solid #2f6fab; border-style: solid solid none solid; padding: 0 1em 0 1em; /* text-transform: lowercase; /* force text to lowercase */ /* text-transform: uppercase; /* force text to uppercase */ text-transform: capitalize; /* force text to proper case */ display: block; <pre>#p-personal ul { text-transform: capitalize;
#p-cactions li a { /* text-transform: lowercase; */ text-transform: capitalize; /* force text to proper case */ }
Edit the Sidebar
Go to http://domain.co.uk/wiki/MediaWiki:Sidebar
Recaptcha installation
First go here and obtain a public and private key for your wiki.
Add the following to LocalSettings.php, below the inclusion of ConfirmEdit:
require_once("$IP/extensions/ConfirmEdit/ReCaptcha.php"); $wgCaptchaClass = 'ReCaptcha'; $wgReCaptchaPublicKey = 'your public key here'; $wgReCaptchaPrivateKey = 'your private key here';
Short URL configuration
http://www.mediawiki.org/wiki/Manual:Short_URL
vim LocalSettings.php
$wgScriptPath = ""; $wgArticlePath = '/wiki/$1'; $wgUsePathInfo = true; $wgScriptExtension = ".php";
a2enmod rewrite /etc/init.d/apache2 restart vim /etc/apache2/sites-available/domain.co.uk
RewriteEngine On RewriteRule ^/?wiki(/.*)?$ %{DOCUMENT_ROOT}/index.php [L] RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d RewriteRule ^/?images/thumb/[0-9a-f]/[0-9a-f][0-9a-f]/([^/]+)/([0-9]+)px-.*$ %{DOCUMENT_ROOT}/thumb.php?f=$1&width=$2 [L,QSA,B] RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d RewriteRule ^/?images/thumb/archive/[0-9a-f]/[0-9a-f][0-9a-f]/([^/]+)/([0-9]+)px-.*$ %{DOCUMENT_ROOT}/thumb.php?f=$1&width=$2&archived=1 [L,QSA,B]
Configure your Virtual Host extras here and add the config to the file above and LocalSettings.php: http://shorturls.redwerks.org
Old edited Special:AllMessages
"To protect the wiki against automated account creation, we kindly ask you to solve the simple sum below and enter the answer in the box (more info):"
with the following extract from /extensions/ConfirmEdit/ReCaptcha.i18n.php
"To help protect against automated page creation, please type the two words you see in the box below (more info):"
Migrating to a new server
On the original server, do this:
mysqldump --default-character-set=binary --user=root --password=EnterPasswordHere databasename > dbdump.txt or mysqldump --default-character-set=binary --user=root databasename > dbdump.txt -p
Then copy all your content and the dbdump.txt file across to the new server.
To delete a useless database, do this from within MySQL:
DROP DATABASE wikidb;
You will need to create an empty database first:
create database DatabaseName;
Then on the new server do:
mysql --silent --local --password=EnterPasswordHere DatabaseName < dbdump.txt or mysql --silent --local DatabaseName < dbdump.txt -p
Go into MySQL and create the MySQL user from the old server (specified in LocalSettings.php on the original server) by doing:
create user 'DatabaseUser'@'localhost' identified by 'password'; GRANT ALL PRIVILEGES ON DatabaseName.* TO 'DatabaseUser'@'%' IDENTIFIED BY 'password' WITH GRANT OPTION ;
Edit your LocalSettings.php to ensure the following setting are correct:
$wgDBtype = "mysql";
$wgDBserver = "localhost";
$wgDBname = "DatabaseName";
$wgDBuser = "DatabaseUser";
$wgDBpassword = "DatabaseUserPassword*";
Lock down mw-config directory
Access your install via command line, and set the permissions of the directory to restricted. On Linux, this is done like so:
chmod 000 mw-config
Sitemap
http://www.mediawiki.org/wiki/Extension:ManualSitemap
cp maintenance/generateSitemap.php maintenance/generateSitemap.php.bak
vim maintenance/generateSitemap.php
http://www.mediawiki.org/wiki/User:Superxain/GenerateSitemap (from here)
Spam accounts
ServerKB over 4 years (2021 to 2025) had ~300,000 spam pages and ~20,000 spam accounts created. To save someone the hassle I went to trying to remove all these over a couple of days I documented the steps and tools I used below.
Stats can be checked for your own MediaWiki via these pages: Special:ListUsers Special:Statistics You will want to use these pages throughout your analysis and resolution to keep an eye on the numbers.
If you do not wish to follow the below, you can instead export the known good pages, create a new database, update mediawiki and import the good pages.
First recommendation, upgrade MediaWiki to the latest version possible: https://www.mediawiki.org/wiki/Manual:Upgrading As always, make a backup of your database before upgrading. Make sure you read the deprecated LocalSettings.php options between updates as well as disabling extensions that are not supported or up to date then enabling them after the upgrade (if compatible).
In the case of ServerKB, I upgraded from 1.36 up to 1.42 via 1.36 > 1.37 > 1.38 > 1.42 This did require downgrading PHP from 8.3 to 8.1.
If at any time during this process you run php scripts e.g.
php maintenance/runJobs.php php maintenance/run.php update
And get the following type of errors:
[4758ee24ec3e12702aba0fed] [no req] Error: Call to a member function setHook() on null Backtrace: from extensions/analytics.php(23) #0 includes/Setup.php(571): wfAnalytics() #1 maintenance/doMaintenance.php(83): require_once(string) #2 maintenance/runJobs.php(136): require_once(string) #3 {main} [026858f401e7f387106a367e] [no req] Error: Call to a member function setHook() on null Backtrace: from extensions/analytics.php(23) #0 includes/Setup.php(571): wfAnalytics() #1 maintenance/run.php(49): require_once(string) #2 {main}
You should comment out all extensions (from both wfload and require_once) in LocalSettings.php as these were how I resolved these issues with an old unsupported captcha extension.
During the upgrades, you will need to run this command regularly:
php update.php
I would recommend doing this with your web server (Apache) and database (MySQL) in a stopped state, as this allows you to correct any issues that halt the update/upgrade e.g. missing extensions, missing extension files, missing LocalSettings.php
Note: Tools like BlockAndNuke (deprecated), NukeDPL, SmiteSpam and UserMerge (only supports 1 user at a time) did not work for me as they were either not supported on my version of MediaWiki, out of date, not supported any more or just didn't work. This guide seemed good but fell short as it didn't work for me: https://www.simplecloudworks.com/how-to-delete-a-long-list-of-spam-users-in-mediawiki/
You will then want to utilise the following scripts via command line:
Deleting multiple pages on mass
https://www.mediawiki.org/wiki/Help:Extension:Nuke
Nuke is best used when you haven't updated anything for over 30 days but the spammers have, but you can update LocalSettings.php to increase this check threshold:
$wgNukeMaxAge = <days> * 86400;
Special:AncientPages and Special:RecentChanges are both useful for checking older pages vs newer spam pages.
You can delete pages via SQL for pages edited before or after a certain date using this method: https://stackoverflow.com/questions/8839603/remove-mediawiki-pages-before-a-certain-date
https://www.mediawiki.org/wiki/Extension:DeleteBatch
The best way to use DeleteBatch for "User" pages (User namespace) is to get the list of spam accounts either from the database user table (using user_name) or from Special:ListUsers 500 at a time, copying these into a notepad (to remove formatting), save the file, then open the file in Excel using the bracket symbol as the delimiter, find and replace where needed to remove text you don't want (e.g. talk contrib block)
Use "=CONCATENATE("User:", C1)" in Excel to add the prefix for removing user pages via DeleteBatch.
You basically want to go from this:
"MamieNewquist0 "
to this:
User:MamieNewquist0
Use "=TRIM(A1)" in Excel to remove/strip spaces after usernames if needed. For accounts that are just numbers, be careful when Excel auto-formats the cells with these account names as it can often strip numbers or convert them.
Then you can call a long list of user pages from one text file like so:
php maintenance/run.php deleteBatch /root/userpages.txt
Deleting unused accounts
Check your active users first via Special:ActiveUsers
https://www.mediawiki.org/wiki/Manual:RemoveUnusedAccounts.php
php maintenance/run.php removeUnusedAccounts --delete --ignore-groups administrators,Administrators,administrator,bureaucrats
Note: this only works for accounts that have never made any edits or contributions INCLUDING deleted edits/contributions.
Deleting archived revisions
https://www.mediawiki.org/wiki/Manual:DeleteArchivedRevisions.php
php maintenance/run.php deleteArchivedRevisions --delete
I would also recommend running RemoveUnusedAccounts again after running DeleteArchivedRevisions.
Deleting accounts that made contributions/edits
https://superuser.com/questions/600818/how-do-i-delete-all-non-confirmed-users-in-mediawiki
mysql> DELETE FROM user WHERE NOT user_name='<insert_your_admin_account_here>'; Query OK, 14536 rows affected (1.60 sec)
Fix statistics
https://www.mediawiki.org/wiki/Manual:InitSiteStats.php
php maintenance/run.php initSiteStats --update
Follow up recommendations
https://www.mediawiki.org/wiki/User:Neoshinji#Prevent_spam_bots_from_registering https://www.mediawiki.org/wiki/Manual_talk:Combating_spam https://www.mediawiki.org/wiki/Manual:Combating_spam#:~:text=Extension%3AAbuseFilter%20allows%20privileged%20users,links%20added%2C%20and%20so%20on. https://www.mediawiki.org/wiki/Extension:ConfirmEdit#QuestyCaptcha
If you use Cloudflare: https://community.cloudflare.com/t/page-country-redirect-possible-with-cloudflare/485283 https://tenten.co/insight/dev/country-redirect-with-cloudflare/#:~:text=To%20redirect%20based%20on%20the,country%20variable%20for%20this.