User:Darkshines~metawiki/Hacks/Variables In Extension Tag

From Meta, a Wikimedia project coordination wiki

This patch allows you to use template variables in extension tags (thanks to Mikesch Nepomuk for the base code; I made it suitable for the current release 1.5 beta 5).

--- ParserOld.php	2005-08-23 12:39:43.000000000 +0000
+++ Parser.php	2005-08-23 12:57:30.000000000 +0000
@@ -103,6 +103,8 @@
 	var $mVariables, $mIncludeCount, $mArgStack, $mLastSection, $mInPre;
 	var $mInterwikiLinkHolders, $mLinkHolders;
 
+	var $mStripStateClear;
+
 	# Temporary:
 	var $mOptions, $mTitle, $mOutputType,
 	    $mTemplates,	// cache of already loaded templates, avoids
@@ -188,6 +190,7 @@
 
 		wfRunHooks( 'ParserBeforeStrip', array( &$this, &$text, &$x ) );
 		$text = $this->strip( $text, $x );
+		$text = $this->stripExtensions( $text, $x );
 		wfRunHooks( 'ParserAfterStrip', array( &$this, &$text, &$x ) );
 
 		$text = $this->internalParse( $text );
@@ -343,7 +346,6 @@
 		$math_content = array();
 		$pre_content = array();
 		$comment_content = array();
-		$ext_content = array();
 		$ext_tags = array();
 		$ext_params = array();
 		$gallery_content = array();
@@ -419,6 +421,47 @@
 			}
 		}
 
+		if ($state) {
+			$this->mStripStateClear = false;
+			$state['html'] = $state['html'] + $html_content;
+			$state['nowiki'] = $state['nowiki'] + $nowiki_content;
+			$state['math'] = $state['math'] + $math_content;
+			$state['pre'] = $state['pre'] + $pre_content;
+			$state['comment'] = $state['comment'] + $comment_content;
+			$state['gallery'] = $state['gallery'] + $gallery_content;
+		} else {
+			$this->mStripStateClear = true;
+			$state = array(
+			 'html' => $html_content,
+			 'nowiki' => $nowiki_content,
+			 'math' => $math_content,
+			 'pre' => $pre_content,
+			 'comment' => $comment_content,
+			 'gallery' => $gallery_content,
+			);
+		}
+		return $text;
+	}
+
+	/**
+	 * Strips and renders extensions
+	 * If $render is set, performs necessary rendering operations on plugins
+	 * Returns the text, and fills an array with data needed in unstrip()
+	 * If the $state is already a valid strip state, it adds to the state
+	 *
+	 * @param bool $stripcomments when set, HTML comments 
+ 	 *  will be stripped in addition to other tags. This is important
+	 *  for section editing, where these comments cause confusion when
+	 *  counting the sections in the wikisource
+	 *
+	 * @access private
+	 */
+	function stripExtensions( $text, &$state, $stripcomments = false ) {
+		$render = ($this->mOutputType == OT_HTML);
+		$ext_content = array();
+		# Replace any instances of the placeholders
+		$uniq_prefix = UNIQ_PREFIX;
+		
 		# Extensions
 		foreach ( $this->mTagHooks as $tag => $callback ) {
 			$ext_content[$tag] = array();
@@ -436,28 +479,14 @@
 		}
 
 		# Merge state with the pre-existing state, if there is one
-		if ( $state ) {
-			$state['html'] = $state['html'] + $html_content;
-			$state['nowiki'] = $state['nowiki'] + $nowiki_content;
-			$state['math'] = $state['math'] + $math_content;
-			$state['pre'] = $state['pre'] + $pre_content;
-			$state['comment'] = $state['comment'] + $comment_content;
-			$state['gallery'] = $state['gallery'] + $gallery_content;
-
+		if ( !$this->mStripStateClear ) {
 			foreach( $ext_content as $tag => $array ) {
 				if ( array_key_exists( $tag, $state ) ) {
 					$state[$tag] = $state[$tag] + $array;
 				}
 			}
 		} else {
-			$state = array(
-			  'html' => $html_content,
-			  'nowiki' => $nowiki_content,
-			  'math' => $math_content,
-			  'pre' => $pre_content,
-			  'comment' => $comment_content,
-			  'gallery' => $gallery_content,
-			) + $ext_content;
+			$state = $state + $ext_content;
 		}
  		return $text;
 	}
@@ -2280,9 +2309,13 @@
 
 			if( $this->mOutputType == OT_HTML ) {
 				$text = $this->strip( $text, $this->mStripState );
-				$text = Sanitizer::removeHTMLtags( $text, array( &$this, 'replaceVariables' ), $assocArgs );
 			}
 			$text = $this->replaceVariables( $text, $assocArgs );
+			$text = $this->stripExtensions( $text, $this->mStripState );
+			
+			if ( $this->mOutputType == OT_HTML ) {
+				$text = Sanitizer::removeHTMLtags( $text, array( &$this, 'replaceVariables' ), $assocArgs );
+			}
 
 			# Resume the link cache and register the inclusion as a link
 			if ( $this->mOutputType == OT_HTML && !is_null( $title ) ) {
@@ -2827,6 +2860,7 @@
 		);
 		$text = str_replace( array_keys( $pairs ), array_values( $pairs ), $text );
 		$text = $this->strip( $text, $stripState, false );
+		$text = $this->stripExtensions( $text, $stripState, false );
 		$text = $this->pstPass2( $text, $user );
		$text = $this->unstrip( $text, $stripState );
 		$text = $this->unstripNoWiki( $text, $stripState );


How it works[edit]

Template variables aren't expanded (yet) in extension tags because extension tags are escaped by being replaced with an unique id along with possible variables inside them at almost the start of parsing. Then all formatting like variable expansion is done and after that the unique id's are replaced by the processed extensions. By escaping the extensions after expanding the variables, which is done in the patch, it is possible to use template variables inside the tag.



Bas Westerbaan
bas.westerbaan@gmail.com
Bas's blog