Created
February 15, 2026 11:26
-
-
Save ciencia/f26ae33007b96304bf6c02e34462c13f to your computer and use it in GitHub Desktop.
ext-DisplayTitle-excludenamespaces-REL1_43
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| commit a4f33443bdcf471633ac1641c5f3ad65082f7038 | |
| Exclude links to pages in configurable namespaces | |
| Allow to customize which namespaces shouldn't get affected by | |
| DisplayTitle when linking to them. | |
| This would allow excluding the User: namespace, for example, to prevent | |
| abuse. | |
| Bug: T416942 | |
| Change-Id: I679fa46675ee11a36ef52dfda9c9e1da75f4cc04 | |
| diff --git a/extension.json b/extension.json | |
| index cc7602a..269dab2 100644 | |
| --- a/extension.json | |
| +++ b/extension.json | |
| @@ -54,6 +54,9 @@ | |
| "DisplayTitleExcludes": { | |
| "value": [] | |
| }, | |
| + "DisplayTitleExcludeLinksToNamespaces": { | |
| + "value": [] | |
| + }, | |
| "DisplayTitleFollowRedirects": { | |
| "value": true | |
| } | |
| diff --git a/includes/DisplayTitleService.php b/includes/DisplayTitleService.php | |
| index 2b1fd10..aece07f 100644 | |
| --- a/includes/DisplayTitleService.php | |
| +++ b/includes/DisplayTitleService.php | |
| @@ -34,6 +34,7 @@ class DisplayTitleService { | |
| public const CONSTRUCTOR_OPTIONS = [ | |
| 'DisplayTitleHideSubtitle', | |
| 'DisplayTitleExcludes', | |
| + 'DisplayTitleExcludeLinksToNamespaces', | |
| 'DisplayTitleFollowRedirects' | |
| ]; | |
| @@ -47,6 +48,11 @@ class DisplayTitleService { | |
| */ | |
| private $excludes; | |
| + /** | |
| + * @var array | |
| + */ | |
| + private readonly array $excludeLinksToNamespaces; | |
| + | |
| /** | |
| * @var bool | |
| */ | |
| @@ -89,6 +95,7 @@ class DisplayTitleService { | |
| $options->assertRequiredOptions( self::CONSTRUCTOR_OPTIONS ); | |
| $this->hideSubtitle = $options->get( 'DisplayTitleHideSubtitle' ); | |
| $this->excludes = $options->get( 'DisplayTitleExcludes' ); | |
| + $this->excludeLinksToNamespaces = $options->get( 'DisplayTitleExcludeLinksToNamespaces' ); | |
| $this->followRedirects = $options->get( 'DisplayTitleFollowRedirects' ); | |
| $this->namespaceInfo = $namespaceInfo; | |
| $this->redirectLookup = $redirectLookup; | |
| @@ -115,6 +122,11 @@ class DisplayTitleService { | |
| return; | |
| } | |
| + // Do not use DisplayTitle if the target title namespace is defined in $wgDisplayTitleExcludeLinksToNamespaces | |
| + if ( in_array( $target->getNamespace(), $this->excludeLinksToNamespaces ) ) { | |
| + return; | |
| + } | |
| + | |
| // Do not use DisplayTitle if the current page is a redirect to the page being linked | |
| $title = Title::newFromText( $pageTitle ); | |
| if ( $title->canExist() ) { | |
| diff --git a/tests/phpunit/DisplayTitleTest.php b/tests/phpunit/DisplayTitleTest.php | |
| index bef789b..cbae716 100644 | |
| --- a/tests/phpunit/DisplayTitleTest.php | |
| +++ b/tests/phpunit/DisplayTitleTest.php | |
| @@ -902,4 +902,121 @@ class DisplayTitleTest extends MediaWikiIntegrationTestCase { | |
| '[[redirect To Dingo Page|Redirect To Dingo Page]]' | |
| ]; | |
| } | |
| + | |
| + /** | |
| + * @dataProvider provideTestExcludeLinksToNamespaces | |
| + */ | |
| + public function testExcludeLinksToNamespaces( $testName, $titleText, $wikitext, $extraPages, $expectedLinkText ) { | |
| + $this->overrideConfigValue( 'DisplayTitleExcludeLinksToNamespaces', [ NS_USER ] ); | |
| + Title::clearCaches(); | |
| + $wikiPageFactory = $this->getServiceContainer()->getWikiPageFactory(); | |
| + | |
| + $user = $this->getTestSysop()->getUser(); | |
| + foreach ( $extraPages as $extraTitle => $extraWikitext ) { | |
| + $page = $wikiPageFactory->newFromTitle( Title::newFromText( $extraTitle ) ); | |
| + $updater = $page->newPageUpdater( $user ); | |
| + $updater->setContent( 'main', new WikitextContent( $extraWikitext ) ); | |
| + $updater->saveRevision( | |
| + CommentStoreComment::newUnsavedComment( 'new test page' ), | |
| + EDIT_AUTOSUMMARY | |
| + ); | |
| + } | |
| + | |
| + $title = Title::newFromText( $titleText ); | |
| + $content = new WikitextContent( $wikitext ); | |
| + $parserOptions = new ParserOptions( $user ); | |
| + $parserOptions->setRemoveComments( true ); | |
| + $contentRenderer = $this->getServiceContainer()->getContentRenderer(); | |
| + $parserOutput = $contentRenderer->getParserOutput( $content, $title->toPageIdentity(), null, $parserOptions ); | |
| + $actual = $parserOutput->runOutputPipeline( $parserOptions )->getContentHolderText(); | |
| + | |
| + $this->assertStringContainsString( '>' . $expectedLinkText . '</a>', $actual, $testName ); | |
| + } | |
| + | |
| + public function provideTestExcludeLinksToNamespaces() { | |
| + // link to user page with display title | |
| + $extraPages = [ | |
| + 'User:Dingo Page' => '{{DISPLAYTITLE:Zebra}}' | |
| + ]; | |
| + | |
| + yield [ | |
| + 'Link to user page with display title, no link text', | |
| + 'Test Page', | |
| + '[[User:Dingo Page]]', | |
| + $extraPages, | |
| + 'User:Dingo Page' | |
| + ]; | |
| + | |
| + yield [ | |
| + 'Link to user page with display title, lower case page title, no link text', | |
| + 'Test Page', | |
| + '[[User:dingo Page]]', | |
| + $extraPages, | |
| + 'User:dingo Page' | |
| + ]; | |
| + | |
| + yield [ | |
| + 'Link to user page with display title, fragment, no link text', | |
| + 'Test Page', | |
| + '[[User:Dingo Page#Fragment]]', | |
| + $extraPages, | |
| + 'User:Dingo Page#Fragment' | |
| + ]; | |
| + | |
| + yield [ | |
| + 'Link to user page with display title, page name link text', | |
| + 'Test Page', | |
| + '[[User:Dingo Page|User:Dingo Page]]', | |
| + $extraPages, | |
| + 'User:Dingo Page' | |
| + ]; | |
| + | |
| + yield [ | |
| + 'Link to user page with display title, page name with underscores link text', | |
| + 'Test Page', | |
| + '[[User:Dingo Page|User:Dingo_Page]]', | |
| + $extraPages, | |
| + 'User:Dingo_Page' | |
| + ]; | |
| + | |
| + yield [ | |
| + 'Link to user page with display title, lowercase page name, page name link text', | |
| + 'Test Page', | |
| + '[[User:dingo Page|User:Dingo Page]]', | |
| + $extraPages, | |
| + 'User:Dingo Page' | |
| + ]; | |
| + | |
| + yield [ | |
| + 'Link to user page with display title, lowercase page name, lowercase page name link text', | |
| + 'Test Page', | |
| + '[[User:dingo Page|User:dingo Page]]', | |
| + $extraPages, | |
| + 'User:dingo Page' | |
| + ]; | |
| + | |
| + yield [ | |
| + 'Link to user page with display title, lowercase page name link text', | |
| + 'Test Page', | |
| + '[[User:Dingo Page|User:dingo Page]]', | |
| + $extraPages, | |
| + 'User:dingo Page' | |
| + ]; | |
| + | |
| + yield [ | |
| + 'Link to user page with display title, other link text', | |
| + 'Test Page', | |
| + '[[User:Dingo Page|Coyote]]', | |
| + $extraPages, | |
| + 'Coyote' | |
| + ]; | |
| + | |
| + yield [ | |
| + 'Link to user page with display title, lowercase page name, other link text', | |
| + 'Test Page', | |
| + '[[User:dingo Page|Coyote]]', | |
| + $extraPages, | |
| + 'Coyote' | |
| + ]; | |
| + } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment