From b2a84fbe87da22818e170575ba364cb9201d6f6c Mon Sep 17 00:00:00 2001 From: UltrasonicNXT Date: Thu, 21 Nov 2013 19:38:34 +0000 Subject: [PATCH] Move ExpandTemplates special into core Very little modification to extension, add some docs, and GNU license as per the other core extensions. Removed $isNewParser, as it won't be needed with new versions of MW, and changed the name of POST variables used. I have not moved across any of the messages except english, according to the bug report, translatewiki will sort this out. The expandtemplates message section has also been added to messages.inc. htmlspecialchars should not be performed on anything, as it will cause it to render like <root> Added this change into the 1.23 release notes. Bug: 28264 Change-Id: I7ef63488dc3ad3885bcf99ff52852e1c6981942b --- RELEASE-NOTES-1.23 | 1 + includes/AutoLoader.php | 1 + includes/SpecialPageFactory.php | 1 + includes/specials/SpecialExpandTemplates.php | 229 +++++++++++++++++++ languages/messages/MessagesEn.php | 20 ++ maintenance/language/messages.inc | 15 ++ 6 files changed, 267 insertions(+) create mode 100644 includes/specials/SpecialExpandTemplates.php diff --git a/RELEASE-NOTES-1.23 b/RELEASE-NOTES-1.23 index 806883db32..2d89dd2f04 100644 --- a/RELEASE-NOTES-1.23 +++ b/RELEASE-NOTES-1.23 @@ -83,6 +83,7 @@ changes to languages because of Bugzilla reports. * The global functions addButton and insertTags (for mw.toolbar.addButton and mw.toolbar.insertTags) now emits mw.log.warn when accessed. * User::getPageRenderingHash() was deprecated since 1.17 and has been removed. +* The ExpandTemplates extension has been moved into MediaWiki core. == Compatibility == diff --git a/includes/AutoLoader.php b/includes/AutoLoader.php index 1770e0449a..3c538b0665 100644 --- a/includes/AutoLoader.php +++ b/includes/AutoLoader.php @@ -958,6 +958,7 @@ $wgAutoloadLocalClasses = array( 'SpecialContributions' => 'includes/specials/SpecialContributions.php', 'SpecialEditWatchlist' => 'includes/specials/SpecialEditWatchlist.php', 'SpecialEmailUser' => 'includes/specials/SpecialEmailuser.php', + 'SpecialExpandTemplates' => 'includes/specials/SpecialExpandTemplates.php', 'SpecialExport' => 'includes/specials/SpecialExport.php', 'SpecialFilepath' => 'includes/specials/SpecialFilepath.php', 'SpecialImport' => 'includes/specials/SpecialImport.php', diff --git a/includes/SpecialPageFactory.php b/includes/SpecialPageFactory.php index 1ede0c17c5..9542654540 100644 --- a/includes/SpecialPageFactory.php +++ b/includes/SpecialPageFactory.php @@ -149,6 +149,7 @@ class SpecialPageFactory { 'Undelete' => 'SpecialUndelete', 'Whatlinkshere' => 'SpecialWhatlinkshere', 'MergeHistory' => 'SpecialMergeHistory', + 'ExpandTemplates' => 'SpecialExpandTemplates', // Other 'Booksources' => 'SpecialBookSources', diff --git a/includes/specials/SpecialExpandTemplates.php b/includes/specials/SpecialExpandTemplates.php new file mode 100644 index 0000000000..b566b918d0 --- /dev/null +++ b/includes/specials/SpecialExpandTemplates.php @@ -0,0 +1,229 @@ + tags in the expanded wikitext */ + protected $removeNowiki; + + /** @var maximum size in bytes to include. 50MB allows fixing those huge pages */ + const MAX_INCLUDE_SIZE = 50000000; + + function __construct() { + parent::__construct( 'ExpandTemplates' ); + } + + /** + * Show the special page + */ + function execute( $subpage ) { + global $wgParser, $wgUseTidy, $wgAlwaysUseTidy; + + $this->setHeaders(); + + $request = $this->getRequest(); + $titleStr = $request->getText( 'wpContextTitle' ); + $title = Title::newFromText( $titleStr ); + + if ( !$title ) { + $title = $this->getTitle(); + } + $input = $request->getText( 'wpInput' ); + $this->generateXML = $request->getBool( 'wpGenerateXml' ); + + if ( strlen( $input ) ) { + $this->removeComments = $request->getBool( 'wpRemoveComments', false ); + $this->removeNowiki = $request->getBool( 'wpRemoveNowiki', false ); + $options = ParserOptions::newFromContext( $this->getContext() ); + $options->setRemoveComments( $this->removeComments ); + $options->setTidy( true ); + $options->setMaxIncludeSize( self::MAX_INCLUDE_SIZE ); + + if ( $this->generateXML ) { + $wgParser->startExternalParse( $title, $options, OT_PREPROCESS ); + $dom = $wgParser->preprocessToDom( $input ); + + if ( method_exists( $dom, 'saveXML' ) ) { + $xml = $dom->saveXML(); + } else { + $xml = $dom->__toString(); + } + } + + $output = $wgParser->preprocess( $input, $title, $options ); + } else { + $this->removeComments = $request->getBool( 'wpRemoveComments', true ); + $this->removeNowiki = $request->getBool( 'wpRemoveNowiki', false ); + $output = false; + } + + $out = $this->getOutput(); + $out->addWikiMsg( 'expand_templates_intro' ); + $out->addHTML( $this->makeForm( $titleStr, $input ) ); + + if( $output !== false ) { + if ( $this->generateXML && strlen( $output ) > 0 ) { + $out->addHTML( $this->makeOutput( $xml, 'expand_templates_xml_output' ) ); + } + + $tmp = $this->makeOutput( $output ); + + if ( $this->removeNowiki ) { + $tmp = preg_replace( + array( '_<nowiki>_', '_</nowiki>_', '_<nowiki */>_' ), + '', + $tmp + ); + } + + if( ( $wgUseTidy && $options->getTidy() ) || $wgAlwaysUseTidy ) { + $tmp = MWTidy::tidy( $tmp ); + } + + $out->addHTML( $tmp ); + $this->showHtmlPreview( $title, $output, $out ); + } + + } + + /** + * Generate a form allowing users to enter information + * + * @param string $title Value for context title field + * @param string $input Value for input textbox + * @return string + */ + private function makeForm( $title, $input ) { + $self = $this->getTitle(); + $form = Xml::openElement( + 'form', + array( 'method' => 'post', 'action' => $self->getLocalUrl() ) + ); + $form .= "
" . $this->msg( 'expandtemplates' )->escaped() . "\n"; + + $form .= '

' . Xml::inputLabel( + $this->msg( 'expand_templates_title' )->plain(), + 'wpContextTitle', + 'contexttitle', + 60, + $title, + array( 'autofocus' => true ) + ) . '

'; + $form .= '

' . Xml::label( + $this->msg( 'expand_templates_input' )->text(), + 'input' + ) . '

'; + $form .= Xml::textarea( + 'wpInput', + $input, + 10, + 10, + array( 'id' => 'input' ) + ); + + $form .= '

' . Xml::checkLabel( + $this->msg( 'expand_templates_remove_comments' )->text(), + 'wpRemoveComments', + 'removecomments', + $this->removeComments + ) . '

'; + $form .= '

' . Xml::checkLabel( + $this->msg( 'expand_templates_remove_nowiki' )->text(), + 'wpRemoveNowiki', + 'removenowiki', + $this->removeNowiki + ) . '

'; + $form .= '

' . Xml::checkLabel( + $this->msg( 'expand_templates_generate_xml' )->text(), + 'wpGenerateXml', + 'generate_xml', + $this->generateXML + ) . '

'; + $form .= '

' . Xml::submitButton( + $this->msg( 'expand_templates_ok' )->text(), + array( 'accesskey' => 's' ) + ) . '

'; + $form .= "
\n"; + $form .= Xml::closeElement( 'form' ); + + return $form; + } + + /** + * Generate a nice little box with a heading for output + * + * @param string $output Wiki text output + * @param string $heading + * @return string + */ + private function makeOutput( $output, $heading = 'expand_templates_output' ) { + $out = "

" . $this->msg( $heading )->escaped() . "

\n"; + $out .= Xml::textarea( + 'output', + $output, + 10, + 10, + array( 'id' => 'output', 'readonly' => 'readonly' ) + ); + + return $out; + } + + /** + * Render the supplied wiki text and append to the page as a preview + * + * @param Title $title + * @param string $text + * @param OutputPage $out + */ + private function showHtmlPreview( Title $title, $text, OutputPage $out ) { + global $wgParser; + + $popts = ParserOptions::newFromContext( $this->getContext() ); + $popts->setTargetLanguage( $title->getPageLanguage() ); + $pout = $wgParser->parse( $text, $title, $popts ); + $lang = $title->getPageViewLanguage(); + + $out->addHTML( "

" . $this->msg( 'expand_templates_preview' )->escaped() . "

\n" ); + $out->addHTML( Html::openElement( 'div', array( + 'class' => 'mw-content-' . $lang->getDir(), + 'dir' => $lang->getDir(), + 'lang' => $lang->getHtmlCode(), + ) ) ); + + $out->addHTML( $pout->getText() ); + $out->addHTML( Html::closeElement( 'div' ) ); + } +} diff --git a/languages/messages/MessagesEn.php b/languages/messages/MessagesEn.php index 5b175977e2..43b4a475b6 100644 --- a/languages/messages/MessagesEn.php +++ b/languages/messages/MessagesEn.php @@ -406,6 +406,7 @@ $specialPageAliases = array( 'DoubleRedirects' => array( 'DoubleRedirects' ), 'EditWatchlist' => array( 'EditWatchlist' ), 'Emailuser' => array( 'EmailUser' ), + 'ExpandTemplates' => array( 'ExpandTemplates', 'Expantemplates' ), 'Export' => array( 'Export' ), 'Fewestrevisions' => array( 'FewestRevisions' ), 'FileDuplicateSearch' => array( 'FileDuplicateSearch' ), @@ -5147,4 +5148,23 @@ Otherwise, you can use the easy form below. Your comment will be added to the pa 'limitreport-expensivefunctioncount' => 'Expensive parser function count', 'limitreport-expensivefunctioncount-value' => '$1/$2', # only translate this message to other languages if you have to change it +# ExpandTemplates +'expandtemplates' => 'Expand templates', +'expandtemplates-desc' => '[[Special:ExpandTemplates|Expands templates, parser functions + and variables]] to show expanded wikitext and preview rendered page', +'expand_templates_intro' => 'This special page takes text and expands all templates in it +recursively. +It also expands supported parser functions like +{{#language:…}} and variables like +{{CURRENTDAY}}. +In fact, it expands pretty much everything in double-braces.', +'expand_templates_title' => 'Context title, for {{FULLPAGENAME}}, etc.:', +'expand_templates_input' => 'Input text:', +'expand_templates_output' => 'Result', +'expand_templates_xml_output' => 'XML output', +'expand_templates_ok' => 'OK', +'expand_templates_remove_comments' => 'Remove comments', +'expand_templates_remove_nowiki' => 'Suppress tags in result', +'expand_templates_generate_xml' => 'Show XML parse tree', +'expand_templates_preview' => 'Preview', ); diff --git a/maintenance/language/messages.inc b/maintenance/language/messages.inc index 5aa188a97c..b443af45ab 100644 --- a/maintenance/language/messages.inc +++ b/maintenance/language/messages.inc @@ -3975,6 +3975,20 @@ $wgMessageStructure = array( 'limitreport-expensivefunctioncount', 'limitreport-expensivefunctioncount-value', ), + 'expandtemplates' => array( + 'expandtemplates', + 'expandtemplates-desc', + 'expand_templates_intro', + 'expand_templates_title', + 'expand_templates_input', + 'expand_templates_output', + 'expand_templates_xml_output', + 'expand_templates_ok', + 'expand_templates_remove_comments', + 'expand_templates_remove_nowiki', + 'expand_templates_generate_xml', + 'expand_templates_preview', + ), ); /** Comments for each block */ @@ -4222,4 +4236,5 @@ Variants for Chinese language", 'cachedspecial' => 'SpecialCachedPage', 'rotation' => 'Image rotation', 'limitreport' => 'Limit report', + 'expandtemplates' => 'Special:ExpandTemplates' ); -- 2.20.1