Extension:Replace Text

Replace Text is an extension to MediaWiki that provides a special page to allow administrators to do a global string find-and-replace on both the text and titles of the wiki's content pages.

Code and download
You can download the Replace Text code in either one of these two compressed files:


 * replace_text_0.9.3.tar.gz
 * replace_text_0.9.3.zip

You can also download the code directly via SVN from the MediaWiki source code repository, at http://svn.wikimedia.org/svnroot/mediawiki/trunk/extensions/ReplaceText/. From a command line, you can call the following:

To view the code online, including version history for each file, you can go here.

Installation
After you've obtained a 'ReplaceText' directory (either by extracting a compressed file or downloading via SVN), place this directory within the main MediaWiki 'extensions' directory. Then, anywhere in the file 'LocalSettings.php' in the main MediaWiki directory, add the following lines:

By default, only members of the 'sysop' user group have access to the Replace Text functionality. You can add to or modify the set of allowed users by modifying the $wgGroupPermissions array in LocalSettings.php. To add the permission for 'bureaucrat' users, for instance, you would add the following:

Usage
Replace Text defines a special page, at 'Special:ReplaceText' (or its equivalent in another language), that handles global searching and replacing. The page initially displays a form for an administrator to fill out the search-and-replace details: the administrator enters a search string and its replacement, the set of namespaces on which to search, as well as choosing whether to replace text within page contents, page titles, or both. Optionally, the administrator can also add two additional filters: the name of a category that all pages must belong to, and a prefix that all page names must start with. When this form is submitted, they are then shown a list of either all the pages that contain that search string, or all the pages whose titles contain the search string, or both. Next to each page name is a checkbox for each, so that they can unselect whichever pages they don't want replaced. The user then can hit "Replace" to do the actual replacement. Once a text replace is done, it is not directly undoable; though you can always run a "reverse" replace, replacing the new string with the original string. For that reason, if the replacement string is blank or is a string that already exists in the wiki, the user is shown a warning message.

If the search string is contained multiple times on a page, every such instance is replaced. Every page's replacements shows up as a (minor) wiki edit, with the administrator who performed the text replacement as the user who made the edit and an edit summary that looks like "Text replace: ' search string ' to ' replacement string '".

A page's title cannot be moved to a title that already exists in the wiki. Pages that cannot be moved will be simply listed on the "select" page as being unmovable, without a checkbox near them.

The search is case-sensitive.

Using regular expressions
If you click on the "Use regular expressions" checkbox, you can use regular expressions within the search and replacement strings. The set of regular expressions allowed is basically a small subset of the PHP and MySQL regular-expression sets (it has only been tested with MySQL - whether it works on other database systems is unknown). The characters that one can use in the search string are " . * + ? [ ] |", and within the replacement string one can use values like $1, $2 etc. This section will not give a tutorial on using regular expressions (the Wikipedia article is a good place to start for that, as is this page on MySQL regexps), but here is the basic example listed in the inline explanation:


 * Search string: a(.*)c
 * Replacement string: ac$1

This would look for pages containing the letter 'a', the letter 'c', and any text in between (signified by the ".*"). It would then put that middle text after the 'a' and 'c' - the "$1" in the replacement string refers to the first element of the search string contained within parentheses (in this case, there's only one).

For every page for which the replace is actually called, the replacement would happen for every occurrence of the search string, not just one - just as happens with regular, non-regular-expression search.

Further Example (finding many signs and a dot)

 * Search string: keep(.*)\.
 * Replacement string: keep$1,

Task: Replace "keep222." with "keep222," and "keeplola." with "keeplola,"

Search term: First match the word "keep". In parentheses follows an expression to search for any signs ( The dot finds one sign, the star finds many of the search signs that preceded the star). The backslash is an escape sign for the dot in a regular expressions. So the dot preceded by backslash actually finds a dot and not a sign.

Replacement: First we replace the word "keep". $1 replaces everything that was found in (.*), the first expression. This is followed by a comma.

Further Example (finding many digits and a dot)

 * Search string: dontkeep([0-9]*)\.([0-9]*)
 * Replacement string: $1,$2

Task: Replace "dontkeep222.555" with "222,555" and "dontkeep2.55" with "2,55"

Search term: First match the word "dontkeep". In brackets follows an expression to search for any digits "0-9". The following star finds many matches of the preceding element. The brackets and the star get enclosed with parantheses, so we match the complete term and transfer it to $1. The backslash is an escape sign for the dot in a regular expressions. So the dot preceded by backslash actually finds a dot and not a sign. Match again digits and put into $2

Replacement: First we replace the word "dontkeep" with nothing. $1 replaces everything that was found in ([0-9]*), the first expression. This is followed by a comma. $2 replaces everything that was found in ([0-9]*), the second expression.

Authors
Replace Text was mostly written by Yaron Koren, reachable at yaron57 -at- gmail.com. Important contributions were also made by Niklas Laxström and Ankit Garg (who contributed much of the regular expression code).

Version history
Replace Text is currently at version 0.9.3. See the entire version history.

Screenshots
Below are images of the workflow of Replace Text. First, the initial page in which "George F. Will" and "George Will" are entered for the target string and replacement string, respectively, and replacing text in page titles is specified as well, on Discourse DB:



Note: the check "All" and "None" boxes only show up when using the Vector skin, or skins based off of it.

And here is what the page looks like after the user hits "Continue":



Hitting "Replace" would replace this value in all of the listed pages, as well as moving the page at the end to its new value.

Code structure
The following are the files in the Replace Text extension:


 * README - description of the extension
 * ReplaceText.js - Javascript needed for the forms
 * ReplaceText.php - main file
 * ReplaceTextJob.php - class for the MediaWiki job that does the text replacement
 * ReplaceText.alias.php - special-page aliases
 * ReplaceText.i18n.php - language file
 * SpecialReplaceText.php - the "Special" page that provides the interface for the replacement

Known issues

 * The replacement actions themselves are structured as MediaWiki "jobs", to ensure that the system is not overloaded if the user wants to do many at the same time. This means that a large set of replacements will not be done immediately, and may take minutes, hours or even longer to complete. Jobs get activated every time a page is viewed on the wiki; to speed up the process (or slow it down), you change the number of jobs run when a page is viewed; the default is 1. For information on how to change it, see the $wgJobRunRate page.
 * In order for redirects not to be created on page moves, i.e. if the "Save the old titles as redirects to the new titles" checkbox is unchecked, you will have to give the relevant user the 'suppressredirect' permission. Assuming you've given the 'replacetext' permission only to sysops, you would need to add the following to LocalSettings.php:


 * If your revisions are compressed (that is, if $wgCompressRevisions is enabled in LocalSettings.php) then ReplaceText will not work, because it makes use of SQL queries that can't search compressed text.
 * The number of replacements you can do at any time may be limited if you have the Suhosin PHP extension installed on your server. If this is a problem, you can try temporarily disabling it while you do the replacements.

Bugs and feature requests
Send any bug reports and requests to Yaron Koren, at yaron57 -at- gmail.com.

Contributing patches to the project
If you found some bug and fixed it, please create a patch by going to the "ReplaceText" directory, and typing:

svn diff >descriptivename.patch

Then send this patch, with a description, to Yaron Koren.

Translating
Translation of Replace Text is done through translatewiki.net. The translation for this extension can be found here. To add language values or change existing ones, you should create an account on translatewiki.net, then request permission from the administrators to translate a certain language or languages on this page (this is a very simple process). Once you have permission for a given language, you can log in and add or edit whatever messages you want to in that language.