Page MenuHomePhabricator

Send $wgTitle to the fiery pit from whence it came
Open, MediumPublic


$wgTitle is by far the most evil global we have. It needs to go away. It constantly gets in the way of doing things properly, and people use it not knowing how bad it is.

Suggest we make killing this a higher priority. Other globals are bad too, but this one is really really bad.

Event Timeline

bzimport raised the priority of this task from to Low.Nov 21 2014, 11:00 PM
bzimport set Reference to bz23307.
bzimport added a subscriber: Unknown Object (MLST).


172 usages in phase3 including comments? :(

tisane2718 wrote:

Before getting rid of $wgTitle, hooks such as AlternateEdit and ParserBeforeStrip should be modified to provide a $title parameter. The manual page on $wgTitle clearly warns about the problems with that global, but sometimes there's no alternative to using it, the way hooks are currently set up.

ParserBeforeStrip is passed a $parser parameter, so you can grab the title with $parser->getTitle() . Similarly, you can use $ep->getArticle()->getTitle() in AlternateEdit.

Looks like from the API's pov, we can just nuke all the "usages" when they've been removed elsewhere etc.

We're just keeping some crappy compatibility by assigning wgTitle to the one we're currently abusing

The situation is even more grave than I thought, adding the following to parserTests.php indicates that even Parser is dependant on it:

class DummyTitle {
public function __call( $name, $args ) {

		throw new MWException( "\$wgTitle::$name() called" );


$wgTitle = new DummyTitle()

Bryan.TongMinh wrote:

I was looking into this, and it appears that the main culprit is wfMsgExt( $msg, 'parsemag' ), which calls MessageCache::transform and in turn Parser::transformMsg. The way to fix this is to pass a $title object along the entire wfMsg chain.

I used the following code to find out what is calling $wgTitle:

class wgTitleStub extends StubObject {
function __construct( $title ) {

		$this->title = $title;
		parent::__construct( 'wgTitle' );

function _newObject() {

		return $this->title;

function _unstub( $name = '_unstub', $level = 2 ) {

		parent::_unstub( $name, $level );

		$bt = array();
		foreach ( wfDebugBacktrace() as $line ) {
			if ( isset( $line['class'] ) ) {
				$bt[] = "{$line['class']}::{$line['function']}";
			} else {
				$bt[] = $line['function'];
		wfDebug('Full $wgTitle unstub backtrace: ' . implode( ', ', $bt ) . "\n" );


Then in Wiki::performRequestForTitle() remove the pass by reference from the function arguments and set $GLOBALS['wgTitle'] = new wgTitleStub( $title );

changed bug title to be less offending.

(In reply to comment #7)

changed bug title to be less offending.

$wgTitle deserves every bit of it, IMO :)

(In reply to comment #8)

(In reply to comment #7)

changed bug title to be less offending.

$wgTitle deserves every bit of it, IMO :)

Adjusted again.

116 usages in phase3...

Quite a few seem to be back compat setting a value, and/or documentation

LanguageConverter probably wants contextsourcing

See bug 53498 comment 10 for a very nasty bug caused by the usage of $wgTitle in AbuseFilter code

Krinkle set Security to None.
Krinkle removed a subscriber: Unknown Object (MLST).

1MessageCache::parse called by HTMLFormField::__construct/Message::parse/Message::toString/Message::parseText/MessageCache::parse with no title set. 22264
2MessageCache::parse called by Gadget::getDescription/Message::parse/Message::toString/Message::parseText/MessageCache::parse with no title set. 7369
3MessageCache::parse called by UserLoginAndCreateTemplate::getGuiderMessage/Message::parse/Message::toString/Message::parseText/MessageCache::parse with no title set. 6942
4MessageCache::parse called by Flow\TemplateHelper::l10nParse/Message::parse/Message::toString/Message::parseText/MessageCache::parse with no title set. 6017
5MessageCache::parse called by Html::expandAttributes/Message::__toString/Message::toString/Message::parseText/MessageCache::parse with no title set. 4912
6MessageCache::parse called by Html::dropDefaults/Message::__toString/Message::toString/Message::parseText/MessageCache::parse with no title set. 4912
7MessageCache::parse called by Wikibase\Repo\View\SiteLinksView::getHtmlForSiteLinkGroup/Message::parse/Message::toString/Message::parseText/MessageCache::parse with no title set. 4542
8RequestContext::getTitle called by DerivativeContext::msg/Message::setContext/DerivativeContext::getTitle/DerivativeContext::getTitle/RequestContext::getTitle with no title set. 2574
9MessageCache::parse called by EditPage::getCheckboxes/Message::parse/Message::toString/Message::parseText/MessageCache::parse with no title set. 2322
10RequestContext::getTitle called by call_user_func_array/DerivativeContext::msg/Message::setContext/DerivativeContext::getTitle/RequestContext::getTitle with no title set. 1704
11MessageCache::parse called by EditPage::showSummaryInput/Message::parse/Message::toString/Message::parseText/MessageCache::parse with no title set. 1339
12MessageCache::parse called by EditPage::showStandardInputs/Message::parse/Message::toString/Message::parseText/MessageCache::parse with no title set. 1339
13MessageCache::parse called by EditPage::showEditTools/Message::parse/Message::toString/Message::parseText/MessageCache::parse with no title set. 1339
14MessageCache::parse called by EditPage::showEditForm/Message::parse/Message::toString/Message::parseText/MessageCache::parse with no title set. 1339
15MessageCache::parse called by EditPage::getCancelLink/Message::parse/Message::toString/Message::parseText/MessageCache::parse with no title set. 1339
16MessageCache::parse called by UploadWizardHooks::getLicenseMessage/Message::parse/Message::toString/Message::parseText/MessageCache::parse with no title set. 1218
17MessageCache::parse called by GadgetHooks::getPreferences/Message::parse/Message::toString/Message::parseText/MessageCache::parse with no title set. 1137
18RequestContext::getTitle called by LCRun3::ch/call_user_func_array/Flow\TemplateHelper::linkWithReturnTo/Flow\TemplateHelper::addReturnTo/RequestContext::getTitle with no title set. 1136
19MessageCache::parse called by Exception::__construct/Message::__toString/Message::toString/Message::parseText/MessageCache::parse with no title set. 1077
20MessageCache::parse called by LoginForm::execute/LoginForm::addNewAccount/Message::toString/Message::parseText/MessageCache::parse with no title set. 1026
21MessageCache::parse called by FlaggedRevsXML::prettyRatingBox/Message::parse/Message::toString/Message::parseText/MessageCache::parse with no title set. 912
22MessageCache::parse called by Title::getEditNotices/Message::parseAsBlock/Message::toString/Message::parseText/MessageCache::parse with no title set. 685
23MessageCache::parse called by CentralAuthHooks::onGetPreferences/Message::parse/Message::toString/Message::parseText/MessageCache::parse with no title set. 616
24RequestContext::getTitle called by OutputPage::setPageTitle/OutputPage::setHTMLTitle/Message::setContext/DerivativeContext::getTitle/RequestContext::getTitle with no title set. 568
25MessageCache::parse called by ArticleCompileProcessor::compileMetadata/ArticleCompileProcessor::process/ArticleCompileSnippet::compile/ArticleCompileSnippet::generateArticleSnippet/MessageCache::parse with no title set. 535
26MessageCache::parse called by EchoBasicFormatter::format/Message::parse/Message::toString/Message::parseText/MessageCache::parse with no title set. 493
27MessageCache::parse called by EditPage::getPreviewLimitReport/Message::parse/Message::toString/Message::parseText/MessageCache::parse with no title set. 428
28MessageCache::parse called by ApiVisualEditor::diffWikitext/Message::parse/Message::toString/Message::parseText/MessageCache::parse with no title set. 368
29MessageCache::parse called by Wikibase\OutputPageJsConfigBuilder::getCopyrightVar/Message::parse/Message::toString/Message::parseText/MessageCache::parse with no title set. 354
30RequestContext::getTitle called by Hooks::run/AbuseFilterHooks::onEditFilterMergedContent/AbuseFilterHooks::filterEdit/AbuseFilter::filterAction/RequestContext::getTitle with no title set. 304
31RequestContext::getTitle called by Flow\Block\TopicSummaryBlock::setPageTitle/OutputPage::setPageTitle/Message::setContext/DerivativeContext::getTitle/RequestContext::getTitle with no title set. 284
32RequestContext::getTitle called by Flow\Block\TopicSummaryBlock::setPageTitle/OutputPage::setHTMLTitle/Message::setContext/DerivativeContext::getTitle/RequestContext::getTitle with no title set. 284
33RequestContext::getTitle called by Flow\Block\TopicBlock::setPageTitle/OutputPage::setPageTitle/Message::setContext/DerivativeContext::getTitle/RequestContext::getTitle with no title set. 284
34RequestContext::getTitle called by Flow\Block\TopicBlock::setPageTitle/OutputPage::setHTMLTitle/Message::setContext/DerivativeContext::getTitle/RequestContext::getTitle with no title set. 284
35RequestContext::getTitle called by Flow\Block\AbstractBlock::checkSpamFilters/Flow\SpamFilter\Controller::validate/Flow\SpamFilter\AbuseFilter::validate/AbuseFilter::filterAction/RequestContext::getTitle with no title set. 274
36MessageCache::parse called by VisualEditorDataModule::getScript/Message::parse/Message::toString/Message::parseText/MessageCache::parse with no title set. 196
37MessageCache::parse called by SkinMinerva::getHistoryLink/Message::parse/Message::toString/Message::parseText/MessageCache::parse with no title set. 162
38MessageCache::parse called by BetaFeaturesHooks::getPreferences/Message::parse/Message::toString/Message::parseText/MessageCache::parse with no title set. 154
39MessageCache::parse called by GadgetHooks::getPreferences/Message::parseAsBlock/Message::toString/Message::parseText/MessageCache::parse with no title set. 147
40MessageCache::parse called by ImagePage::openShowImage/Message::parse/Message::toString/Message::parseText/MessageCache::parse with no title set. 143
41MessageCache::parse called by ImagePage::makeSizeLink/Message::parse/Message::toString/Message::parseText/MessageCache::parse with no title set. 121
42MessageCache::parse called by include/Message::parse/Message::toString/Message::parseText/MessageCache::parse with no title set. 109
43MessageCache::parse called by ImageHandler::getLongDesc/Message::parse/Message::toString/Message::parseText/MessageCache::parse with no title set. 76
44MessageCache::parse called by ChangeTags::buildTagFilterSelector/Message::parse/Message::toString/Message::parseText/MessageCache::parse with no title set. 72
45RequestContext::getTitle called by Hooks::run/AbuseFilterHooks::onAPIEditBeforeSave/AbuseFilterHooks::filterEdit/AbuseFilter::filterAction/RequestContext::getTitle with no title set. 71
46MessageCache::parse called by EditPage::showDiff/Message::parse/Message::toString/Message::parseText/MessageCache::parse with no title set. 68
47MessageCache::parse called by Html::element/Message::__toString/Message::toString/Message::parseText/MessageCache::parse with no title set. 62
48RequestContext::getTitle called by Flow\Formatter\IRCLineUrlFormatter::formatDescription/Flow\Formatter\AbstractFormatter::getDescription/RequestContext::msg/Message::setContext/RequestContext::getTitle with no title set. 57
49MessageCache::parse called by Wikibase\RepoHooks::onFormat/Message::parse/Message::toString/Message::parseText/MessageCache::parse with no title set. 50
50MessageCache::parse called by Linker::formatTemplates/Message::parseAsBlock/Message::toString/Message::parseText/MessageCache::parse with no title set. 46

demon raised the priority of this task from Low to Medium.Jan 6 2016, 6:05 AM

We should really get this done this year. It's 20-freaking-16.

Change 263029 had a related patch set uploaded (by TTO):
DynamicPageListHooks: Set parser context title

Change 263030 had a related patch set uploaded (by TTO):
Remove some uses of $wgTitle in core

Change 263029 merged by jenkins-bot:
DynamicPageListHooks: Set parser context title

The following extensions in git reference $wgTitle at least once in their source code (WMF-deployed extensions marked with *):

* AbuseFilter
* LiquidThreads
* ProofreadPage
* SecurePoll
* SemanticForms
* SemanticMediaWiki
* SemanticResultFormats
* Validator
* VisualEditor
* Wikibase
* WikibaseQueryEngine
* Wikidata

A couple of non-deployed skins use it as well.

Of the deployed extensions that use it, some only assign to it, and never read from it (except for null checks and the like):

  • AbuseFilter
  • Validator
  • VisualEditor
  • WikibaseQueryEngine

Other deployed extensions actually use its value, and need to be patched:

  • LiquidThreads (used in 2 files)
  • ProofreadPage (used in 1 file)
  • SecurePoll (used once)
  • SemanticForms (used in 6 files)
  • SemanticMediaWiki (used in 2 files)
  • SemanticResultFormats (used in 2 files)
  • Wikibase (used once)
  • Wikidata (used in 2 files)

As usual, SMW is a big offender here.

Change 263030 abandoned by Krinkle:
Remove some uses of $wgTitle in core

All uses in core seem to've been updated in master. Thanks anyway!

Change 938919 had a related patch set uploaded (by Mainframe98; author: Mainframe98):

[mediawiki/core@master] parser: Plug gaps in nullability of Parser::mTitle

Change 938877 had a related patch set uploaded (by Mainframe98; author: Mainframe98):

[mediawiki/core@master] API: Do not initialize $wgTitle to a bad title anymore

Change 938857 had a related patch set uploaded (by Mainframe98; author: Mainframe98):

[mediawiki/core@master] Remove remaining usages of $wgTitle and deprecate it

Just to confirm: the wgTitle JavaScript config value is completely unrelated, and there is no plan to deprecate it ever, right?

Just to confirm: the wgTitle JavaScript config value is completely unrelated, and there is no plan to deprecate it ever, right?

Yes. That's just a string of the current page title and unrelated to this work. Maybe it should be renamed, but that's totally outside of this scope.

Change #1043019 had a related patch set uploaded (by Bartosz Dziewoński; author: Bartosz Dziewoński):

[mediawiki/core@master] Rest: Do not set $wgTitle

Change #1043019 merged by jenkins-bot:

[mediawiki/core@master] Rest: Do not set $wgTitle