From: Alexandre Emsenhuber Date: Tue, 2 Aug 2011 15:40:03 +0000 (+0000) Subject: * (bug 15558) Allow includable special pages to be parameterized using wiki syntax X-Git-Tag: 1.31.0-rc.0~28487 X-Git-Url: http://git.cyclocoop.org/%22%2C%20generer_url_ecrire%28?a=commitdiff_plain;h=700aec37750c93915b32df1b2c2022067c205e0a;p=lhc%2Fweb%2Fwiklou.git * (bug 15558) Allow includable special pages to be parameterized using wiki syntax * Changed SpecialPageFactory::capturePath() to take the same parameters as SpecialPageFactory::executePath() (except the last one) and made it always return a bool instead of bool-or-string. The result HTML can be fetched from the OutputPage object of the context. * Added module styles, scritps and messages members to ParserOutput in addition to modules. The first one is needed to display Special:RecentChanges correctly when transcluded since EnhancedChangesList::beginRecentChangesList() calls addModuleStyles( 'mediawiki.special.changeslist' ) Yes, this means that you can use {{Special:Recentchanges|enhanced=0}} to use the old changes list. For the ones that wonder, {{Special:Recentchanges|uselang=something}} will not work since the Language object is forced to the one used by the parser. --- diff --git a/RELEASE-NOTES-1.19 b/RELEASE-NOTES-1.19 index f1f758bf07..beb19a2135 100644 --- a/RELEASE-NOTES-1.19 +++ b/RELEASE-NOTES-1.19 @@ -23,6 +23,8 @@ production. * (bug 19052) Unicode space separator characters (Zs) now terminates external links and images links. * (bug 30160) Add public method to mw.loader to get module names from registry. +* (bug 15558) Parameters to special pages included in wikitext can now be passed + as with templates. === Bug fixes in 1.19 === * $wgUploadNavigationUrl should be used for file redlinks if diff --git a/includes/OutputPage.php b/includes/OutputPage.php index 7808552951..b1cf069edc 100644 --- a/includes/OutputPage.php +++ b/includes/OutputPage.php @@ -525,6 +525,15 @@ class OutputPage extends ContextSource { $this->mModuleMessages = array_merge( $this->mModuleMessages, (array)$modules ); } + /** + * Get an array of head items + * + * @return Array + */ + function getHeadItemsArray() { + return $this->mHeadItems; + } + /** * Get all header items in a string * @@ -1405,6 +1414,9 @@ class OutputPage extends ContextSource { $this->mNoGallery = $parserOutput->getNoGallery(); $this->mHeadItems = array_merge( $this->mHeadItems, $parserOutput->getHeadItems() ); $this->addModules( $parserOutput->getModules() ); + $this->addModuleScripts( $parserOutput->getModuleScripts() ); + $this->addModuleStyles( $parserOutput->getModuleStyles() ); + $this->addModuleMessages( $parserOutput->getModuleMessages() ); // Template versioning... foreach ( (array)$parserOutput->getTemplateIds() as $ns => $dbks ) { diff --git a/includes/SpecialPageFactory.php b/includes/SpecialPageFactory.php index 1b6be331e3..2b8e173f07 100644 --- a/includes/SpecialPageFactory.php +++ b/includes/SpecialPageFactory.php @@ -471,40 +471,47 @@ class SpecialPageFactory { } /** - * Just like executePath() except it returns the HTML instead of outputting it - * Returns false if there was no such special page, or a title object if it was + * Just like executePath() but will override global variables and execute + * the page in "inclusion" mode. Returns true if the excution was successful + * or false if there was no such special page, or a title object if it was * a redirect. * - * Also saves the current $wgTitle, $wgOut, and $wgRequest variables so that - * the special page will get the context it'd expect on a normal request, - * and then restores them to their previous values after. + * Also saves the current $wgTitle, $wgOut, $wgRequest, $wgUser and $wgLang + * variables so that the special page will get the context it'd expect on a + * normal request, and then restores them to their previous values after. * * @param $title Title + * @param $context RequestContext * * @return String: HTML fragment */ - static function capturePath( &$title ) { - global $wgOut, $wgTitle, $wgRequest; + static function capturePath( Title $title, RequestContext $context ) { + global $wgOut, $wgTitle, $wgRequest, $wgUser, $wgLang; + // Save current globals $oldTitle = $wgTitle; $oldOut = $wgOut; $oldRequest = $wgRequest; + $oldUser = $wgUser; + $oldLang = $wgLang; - // Don't want special pages interpreting ?feed=atom parameters. - $wgRequest = new FauxRequest( array() ); - - $context = new RequestContext; - $context->setTitle( $title ); - $context->setRequest( $wgRequest ); + // Set the globals to the current context + $wgTitle = $title; $wgOut = $context->getOutput(); + $wgRequest = $context->getRequest(); + $wgUser = $context->getUser(); + $wgLang = $context->getLang(); + // The useful part $ret = self::executePath( $title, $context, true ); - if ( $ret === true ) { - $ret = $wgOut->getHTML(); - } + + // And restore that globals $wgTitle = $oldTitle; $wgOut = $oldOut; $wgRequest = $oldRequest; + $wgUser = $oldUser; + $wgLang = $oldLang; + return $ret; } diff --git a/includes/parser/Parser.php b/includes/parser/Parser.php index 614b72aefb..6033b18c26 100644 --- a/includes/parser/Parser.php +++ b/includes/parser/Parser.php @@ -3250,8 +3250,24 @@ class Parser { && $this->mOptions->getAllowSpecialInclusion() && $this->ot['html'] ) { - $text = SpecialPageFactory::capturePath( $title ); - if ( is_string( $text ) ) { + $pageArgs = array(); + for ( $i = 0; $i < $args->getLength(); $i++ ) { + $bits = $args->item( $i )->splitArg(); + if ( strval( $bits['index'] ) === '' ) { + $name = trim( $frame->expand( $bits['name'], PPFrame::STRIP_COMMENTS ) ); + $value = trim( $frame->expand( $bits['value'] ) ); + $pageArgs[$name] = $value; + } + } + $context = new RequestContext; + $context->setTitle( $title ); + $context->setRequest( new FauxRequest( $pageArgs ) ); + $context->setUser( $this->getUser() ); + $context->setLang( Language::factory( $this->mOptions->getUserLang() ) ); + $ret = SpecialPageFactory::capturePath( $title, $context ); + if ( $ret ) { + $text = $context->getOutput()->getHTML(); + $this->mOutput->addOutputPage( $context->getOutput() ); $found = true; $isHTML = true; $this->disableCache(); diff --git a/includes/parser/ParserOutput.php b/includes/parser/ParserOutput.php index 363da78273..aafcee814b 100644 --- a/includes/parser/ParserOutput.php +++ b/includes/parser/ParserOutput.php @@ -130,6 +130,9 @@ class ParserOutput extends CacheTime { $mNoGallery = false, # No gallery on category page? (__NOGALLERY__) $mHeadItems = array(), # Items to put in the section $mModules = array(), # Modules to be loaded by the resource loader + $mModuleScripts = array(), # Modules of which only the JS will be loaded by the resource loader + $mModuleStyles = array(), # Modules of which only the CSSS will be loaded by the resource loader + $mModuleMessages = array(), # Modules of which only the messages will be loaded by the resource loader $mOutputHooks = array(), # Hook tags as per $wgParserOutputHooks $mWarnings = array(), # Warning text to be returned to the user. Wikitext formatted, in the key only $mSections = array(), # Table of contents @@ -195,6 +198,9 @@ class ParserOutput extends CacheTime { function getNoGallery() { return $this->mNoGallery; } function getHeadItems() { return $this->mHeadItems; } function getModules() { return $this->mModules; } + function getModuleScripts() { return $this->mModuleScripts; } + function getModuleStyles() { return $this->mModuleStyles; } + function getModuleMessages() { return $this->mModuleMessages; } function getOutputHooks() { return (array)$this->mOutputHooks; } function getWarnings() { return array_keys( $this->mWarnings ); } function getIndexPolicy() { return $this->mIndexPolicy; } @@ -334,10 +340,36 @@ class ParserOutput extends CacheTime { } } - function addModules( $modules ) { + public function addModules( $modules ) { $this->mModules = array_merge( $this->mModules, (array) $modules ); } + public function addModuleScripts( $modules ) { + $this->mModuleScripts = array_merge( $this->mModuleScripts, (array)$modules ); + } + + public function addModuleStyles( $modules ) { + $this->mModuleStyles = array_merge( $this->mModuleStyles, (array)$modules ); + } + + public function addModuleMessages( $modules ) { + $this->mModuleMessages = array_merge( $this->mModuleMessages, (array)$modules ); + } + + /** + * Copy items from the OutputPage object into this one + * + * @param $out OutputPage object + */ + public function addOutputPage( OutputPage $out ) { + $this->addModules( $out->getModules() ); + $this->addModuleScripts( $out->getModuleScripts() ); + $this->addModuleStyles( $out->getModuleStyles() ); + $this->addModuleMessages( $out->getModuleMessages() ); + + $this->mHeadItems = array_merge( $this->mHeadItems, $out->getHeadItemsArray() ); + } + /** * Override the title to be used for display * -- this is assumed to have been validated