Move ExpandTemplates special into core
authorUltrasonicNXT <adamr_carter@btinternet.com>
Thu, 21 Nov 2013 19:38:34 +0000 (19:38 +0000)
committerUltrasonicNXT <adamr_carter@btinternet.com>
Sat, 23 Nov 2013 16:52:49 +0000 (16:52 +0000)
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 &lt;root&gt;

Added this change into the 1.23 release notes.

Bug: 28264
Change-Id: I7ef63488dc3ad3885bcf99ff52852e1c6981942b

RELEASE-NOTES-1.23
includes/AutoLoader.php
includes/SpecialPageFactory.php
includes/specials/SpecialExpandTemplates.php [new file with mode: 0644]
languages/messages/MessagesEn.php
maintenance/language/messages.inc

index 806883d..2d89dd2 100644 (file)
@@ -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 ==
 
index 1770e04..3c538b0 100644 (file)
@@ -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',
index 1ede0c1..9542654 100644 (file)
@@ -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 (file)
index 0000000..b566b91
--- /dev/null
@@ -0,0 +1,229 @@
+<?php
+/**
+ * Implements Special:ExpandTemplates
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup SpecialPage
+ */
+
+/**
+ * A special page that expands submitted templates, parser functions,
+ * and variables, allowing easier debugging of these.
+ *
+ * @ingroup SpecialPage
+ */
+class SpecialExpandTemplates extends SpecialPage {
+
+       /** @var boolean whether or not to show the XML parse tree */
+       protected $generateXML;
+
+       /** @var boolean whether or not to remove comments in the expanded wikitext */
+       protected $removeComments;
+
+       /** @var boolean whether or not to remove <nowiki> 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( '_&lt;nowiki&gt;_', '_&lt;/nowiki&gt;_', '_&lt;nowiki */&gt;_' ),
+                                       '',
+                                       $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 .= "<fieldset><legend>" . $this->msg( 'expandtemplates' )->escaped() . "</legend>\n";
+
+               $form .= '<p>' . Xml::inputLabel(
+                       $this->msg( 'expand_templates_title' )->plain(),
+                       'wpContextTitle',
+                       'contexttitle',
+                       60,
+                       $title,
+                       array( 'autofocus' => true )
+               ) . '</p>';
+               $form .= '<p>' . Xml::label(
+                       $this->msg( 'expand_templates_input' )->text(),
+                       'input'
+               ) . '</p>';
+               $form .= Xml::textarea(
+                       'wpInput',
+                       $input,
+                       10,
+                       10,
+                       array( 'id' => 'input' )
+               );
+
+               $form .= '<p>' . Xml::checkLabel(
+                       $this->msg( 'expand_templates_remove_comments' )->text(),
+                       'wpRemoveComments',
+                       'removecomments',
+                       $this->removeComments
+               ) . '</p>';
+               $form .= '<p>' . Xml::checkLabel(
+                       $this->msg( 'expand_templates_remove_nowiki' )->text(),
+                       'wpRemoveNowiki',
+                       'removenowiki',
+                       $this->removeNowiki
+               ) . '</p>';
+               $form .= '<p>' . Xml::checkLabel(
+                       $this->msg( 'expand_templates_generate_xml' )->text(),
+                       'wpGenerateXml',
+                       'generate_xml',
+                       $this->generateXML
+               ) . '</p>';
+               $form .= '<p>' . Xml::submitButton(
+                       $this->msg( 'expand_templates_ok' )->text(),
+                       array( 'accesskey' => 's' )
+               ) . '</p>';
+               $form .= "</fieldset>\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 = "<h2>" . $this->msg( $heading )->escaped() . "</h2>\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( "<h2>" . $this->msg( 'expand_templates_preview' )->escaped() . "</h2>\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' ) );
+       }
+}
index 5b17597..43b4a47 100644 (file)
@@ -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
+<code><nowiki>{{</nowiki>#language:…}}</code> and variables like
+<code><nowiki>{{</nowiki>CURRENTDAY}}</code>.
+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 <nowiki> tags in result',
+'expand_templates_generate_xml'    => 'Show XML parse tree',
+'expand_templates_preview'         => 'Preview',
 );
index 5aa188a..b443af4 100644 (file)
@@ -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'
 );