mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/Scribunto
synced 2024-11-24 08:14:09 +00:00
Provide a standard way to get the target of a redirect page
The new Scribunto_LuaTitleLibrary::redirectTarget() method is used by mw.title objects as read-only attribute 'redirectTarget'. If the page does not exist or it is not a redirect, the value of the attribute is `false`; otherwise, it is the target of the redirect page, as mw.title object. This is a proper alternative to parsing wikitext as it is done in: https://en.wikipedia.org/wiki/Module:Redirect Bug: T68974 Change-Id: Id4d9b0f8c1cd09ebc42c031d4d3fc0c33eea44aa
This commit is contained in:
parent
10ebda4a73
commit
1573bee81a
|
@ -18,6 +18,7 @@ class Scribunto_LuaTitleLibrary extends Scribunto_LuaLibraryBase {
|
||||||
'getFileInfo' => array( $this, 'getFileInfo' ),
|
'getFileInfo' => array( $this, 'getFileInfo' ),
|
||||||
'protectionLevels' => array( $this, 'protectionLevels' ),
|
'protectionLevels' => array( $this, 'protectionLevels' ),
|
||||||
'cascadingProtection' => array( $this, 'cascadingProtection' ),
|
'cascadingProtection' => array( $this, 'cascadingProtection' ),
|
||||||
|
'redirectTarget' => array( $this, 'redirectTarget' ),
|
||||||
);
|
);
|
||||||
return $this->getEngine()->registerInterface( 'mw.title.lua', $lib, array(
|
return $this->getEngine()->registerInterface( 'mw.title.lua', $lib, array(
|
||||||
'thisTitle' => $this->getInexpensiveTitleData( $this->getTitle() ),
|
'thisTitle' => $this->getInexpensiveTitleData( $this->getTitle() ),
|
||||||
|
@ -241,11 +242,18 @@ class Scribunto_LuaTitleLibrary extends Scribunto_LuaLibraryBase {
|
||||||
return array( call_user_func_array( array( $title, $func ), $args ) );
|
return array( call_user_func_array( array( $title, $func ), $args ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
function getContent( $text ) {
|
/**
|
||||||
$this->checkType( 'getContent', 1, $text, 'string' );
|
* Utility to get a Content object from a title
|
||||||
|
*
|
||||||
|
* The title is counted as a transclusion.
|
||||||
|
*
|
||||||
|
* @param $text string Title text
|
||||||
|
* @return Content|null The Content object of the title, null if missing
|
||||||
|
*/
|
||||||
|
private function getContentInternal( $text ) {
|
||||||
$title = Title::newFromText( $text );
|
$title = Title::newFromText( $text );
|
||||||
if ( !$title ) {
|
if ( !$title ) {
|
||||||
return array( null );
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Record in templatelinks, so edits cause the page to be refreshed
|
// Record in templatelinks, so edits cause the page to be refreshed
|
||||||
|
@ -261,14 +269,13 @@ class Scribunto_LuaTitleLibrary extends Scribunto_LuaLibraryBase {
|
||||||
} else {
|
} else {
|
||||||
$rev = Revision::newFromTitle( $title );
|
$rev = Revision::newFromTitle( $title );
|
||||||
}
|
}
|
||||||
if ( !$rev ) {
|
return $rev ? $rev->getContent() : null;
|
||||||
return array( null );
|
|
||||||
}
|
}
|
||||||
$content = $rev->getContent();
|
|
||||||
if ( !$content ) {
|
function getContent( $text ) {
|
||||||
return array( null );
|
$this->checkType( 'getContent', 1, $text, 'string' );
|
||||||
}
|
$content = $this->getContentInternal( $text );
|
||||||
return array( $content->serialize() );
|
return array( $content ? $content->serialize() : null );
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFileInfo( $text ) {
|
function getFileInfo( $text ) {
|
||||||
|
@ -355,4 +362,11 @@ class Scribunto_LuaTitleLibrary extends Scribunto_LuaLibraryBase {
|
||||||
'restrictions' => array_map( 'Scribunto_LuaTitleLibrary::makeArrayOneBased', $restrictions )
|
'restrictions' => array_map( 'Scribunto_LuaTitleLibrary::makeArrayOneBased', $restrictions )
|
||||||
) );
|
) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function redirectTarget( $text ) {
|
||||||
|
$this->checkType( 'redirectTarget', 1, $text, 'string' );
|
||||||
|
$content = $this->getContentInternal( $text );
|
||||||
|
$redirTitle = $content ? $content->getRedirectTarget() : null;
|
||||||
|
return array( $redirTitle ? $this->getInexpensiveTitleData( $redirTitle ) : null );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -173,6 +173,7 @@ local function makeTitleObject( data )
|
||||||
isRedirect = 'e',
|
isRedirect = 'e',
|
||||||
contentModel = 'e',
|
contentModel = 'e',
|
||||||
id = 'e',
|
id = 'e',
|
||||||
|
redirectTarget = true,
|
||||||
}
|
}
|
||||||
for k in pairs( data ) do
|
for k in pairs( data ) do
|
||||||
readOnlyFields[k] = true
|
readOnlyFields[k] = true
|
||||||
|
@ -259,6 +260,12 @@ local function makeTitleObject( data )
|
||||||
end
|
end
|
||||||
return data.cascadingProtection
|
return data.cascadingProtection
|
||||||
end
|
end
|
||||||
|
if k == 'redirectTarget' then
|
||||||
|
if data.redirectTarget == nil then
|
||||||
|
data.redirectTarget = makeTitleObject( php.redirectTarget( data.prefixedText ) ) or false
|
||||||
|
end
|
||||||
|
return data.redirectTarget
|
||||||
|
end
|
||||||
|
|
||||||
return data[k]
|
return data[k]
|
||||||
end,
|
end,
|
||||||
|
|
|
@ -48,6 +48,19 @@ class Scribunto_LuaTitleLibraryTests extends Scribunto_LuaEngineTestBase {
|
||||||
new WikitextContent( '{{int:mainpage}}<includeonly>...</includeonly><noinclude>...</noinclude>' ),
|
new WikitextContent( '{{int:mainpage}}<includeonly>...</includeonly><noinclude>...</noinclude>' ),
|
||||||
'Summary'
|
'Summary'
|
||||||
);
|
);
|
||||||
|
$testPageId = $page->getId();
|
||||||
|
|
||||||
|
// Pages for redirectTarget tests
|
||||||
|
$page = WikiPage::factory( Title::newFromText( 'ScribuntoTestRedirect' ) );
|
||||||
|
$page->doEditContent(
|
||||||
|
new WikitextContent( '#REDIRECT [[ScribuntoTestTarget]]' ),
|
||||||
|
'Summary'
|
||||||
|
);
|
||||||
|
$page = WikiPage::factory( Title::newFromText( 'ScribuntoTestNonRedirect' ) );
|
||||||
|
$page->doEditContent(
|
||||||
|
new WikitextContent( 'Not a redirect.' ),
|
||||||
|
'Summary'
|
||||||
|
);
|
||||||
|
|
||||||
// Set restrictions for protectionLevels and cascadingProtection tests
|
// Set restrictions for protectionLevels and cascadingProtection tests
|
||||||
// Since mRestrictionsLoaded is true, they don't count as expensive
|
// Since mRestrictionsLoaded is true, they don't count as expensive
|
||||||
|
@ -88,7 +101,7 @@ class Scribunto_LuaTitleLibraryTests extends Scribunto_LuaEngineTestBase {
|
||||||
// Indicate to the tests that it's safe to create the title objects
|
// Indicate to the tests that it's safe to create the title objects
|
||||||
$interpreter = $this->getEngine()->getInterpreter();
|
$interpreter = $this->getEngine()->getInterpreter();
|
||||||
$interpreter->callFunction(
|
$interpreter->callFunction(
|
||||||
$interpreter->loadString( "mw.title.testPageId = {$page->getId()}", 'fortest' )
|
$interpreter->loadString( "mw.title.testPageId = $testPageId", 'fortest' )
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->setMwGlobals( array(
|
$this->setMwGlobals( array(
|
||||||
|
|
|
@ -71,7 +71,25 @@ local function test_inexpensive()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function test_getContent()
|
local function test_getContent()
|
||||||
return mw.title.new( 'ScribuntoTestPage' ):getContent()
|
return mw.title.new( 'ScribuntoTestPage' ):getContent(),
|
||||||
|
mw.title.new( 'ScribuntoTestNonExistingPage' ):getContent()
|
||||||
|
end
|
||||||
|
|
||||||
|
local function test_redirectTarget()
|
||||||
|
local targets = {}
|
||||||
|
local titles = {
|
||||||
|
'ScribuntoTestRedirect',
|
||||||
|
'ScribuntoTestNonRedirect',
|
||||||
|
'ScribuntoTestNonExistingPage'
|
||||||
|
}
|
||||||
|
for _, title in ipairs( titles ) do
|
||||||
|
local target = mw.title.new( title ).redirectTarget
|
||||||
|
if title.prefixedText ~= nil then
|
||||||
|
target = title.prefixedText
|
||||||
|
end
|
||||||
|
table.insert( targets, target )
|
||||||
|
end
|
||||||
|
return unpack( targets )
|
||||||
end
|
end
|
||||||
|
|
||||||
local function test_getCurrentTitle_fragment()
|
local function test_getCurrentTitle_fragment()
|
||||||
|
@ -372,7 +390,14 @@ local tests = {
|
||||||
},
|
},
|
||||||
|
|
||||||
{ name = '.getContent()', func = test_getContent,
|
{ name = '.getContent()', func = test_getContent,
|
||||||
expect = { '{{int:mainpage}}<includeonly>...</includeonly><noinclude>...</noinclude>' }
|
expect = {
|
||||||
|
'{{int:mainpage}}<includeonly>...</includeonly><noinclude>...</noinclude>',
|
||||||
|
nil,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{ name = '.redirectTarget', func = test_redirectTarget, type = 'ToString',
|
||||||
|
expect = { 'ScribuntoTestTarget', false, false }
|
||||||
},
|
},
|
||||||
|
|
||||||
{ name = 'not quite too many expensive functions', func = test_expensive_10,
|
{ name = 'not quite too many expensive functions', func = test_expensive_10,
|
||||||
|
|
Loading…
Reference in a new issue