QINU fix

From mediawiki.org
See also: Strip marker

See discussion and proposed patch of this issue at task T19329


Problem description and solution[edit]

Some extensions that parse WikiMarkup return strings similar to "UNIQ7dcd9aca33200a81-example-14c1dc322856b22b00000001-QINU" instead of returning what they're supposed to. This seems to be a bug with using global $wgOut; to access the parser. However, since the parser object is passed to the extension callback function (as argument $parser), instead of using global $wgOut;, use the parser object $parser to solve the problem.

Example[edit]

For example, this code may break (it seems inconsistent, or at least in my tests)

<?php
$wgHooks['ParserFirstCallInit'][] = 'wfExampleExtension';

function wfExampleExtension( &$parser ) {
	$parser->setHook( 'example', 'exampleExtension' );
	return true;
}

function exampleExtension( $input, $argv, $parser = null ) {
	global $wgOut;
	$output = $wgOut->parse( $stuff_to_parse, true );
	return $output;
}

The following exampleExtension() function fixes the problem in most cases:

function exampleExtension( $input, $argv, &$parser ) {
	# do some stuff

	$output = $parser->parse(
		$stuff_to_parse, $parser->mTitle,
		$parser->mOptions, true, false
	);
	return $output->getText();
}

The above code will add <p>...</p> around your output. To disable this, just change the fourth argument in the call to $parser->parse() to false:

$output = $parser->parse( $stuff_to_parse, $parser->mTitle, $parser->mOptions, false, false );

However, this won't work if you call it more than once. Instead, instantiate a new parser altogether:

<?php
function myHook( $input, $argv, &$parser ) {
	$localParser = new Parser();
	$output = $localParser->parse(
		$input, $parser->mTitle, $parser->mOptions
	);
	$text = $output->getText();
}

See also the Babel extension for another workaround. Basically, it creates a new parser object, uses that one and then goes back to using the old parser object again. This works around the problem, but it is hacky, bad and not recommended.

If you have to use UNIQ...QINU as input for your function/extension[edit]

Example:

{{#yourhook:{{#foreignHook#:some_code_to_generate_raw_html_which_is_returned_as_UNIQ...QINU(raw_html)}} }}

the parser hides html from wiki with the

return $parser->insertStripItem( $html, $parser->mStripState );

operation in an array inside the mStripeState Object and replaces it with the UNIQ...QINU string instead. when wiki goes over the code, it does not recognize it is html or anything else with importance for wiki and leaves it untouched. and some final workover process, which is definitely after the parser hook stuff, it will replace such UNIQ...QINU strings back with the original raw html. See also Jimbo's page http://web.archive.org/web/20160819183515/http://jimbojw.com/wiki/index.php?title=Raw_HTML_Output_from_a_MediaWiki_Parser_Function

so if you get handed over such an UNIQ...QINU string, it is a random genereated unique key for this array. with this key you can access the corresponding raw html code like this:

<?php
function yourFunction( &$parser, $html = '' ) {
	if ( !( empty( $parser->mStripState->general->data[$html] ) ) ) { 
		$html = ( $parser->mStripState->general->data[$html] );
	}

	// do your stuff

}

where $html is the given UNIQ-string and $parser is the used parser. $html contains after this operation something like this: <a href="link">linktitle</a> if return of foreign function was a link.

voila! you can easily extract everything you need from this string!

Note: The array keys within $parser->mStripState->general->data are wrapped with #7f so $html in the above example also needs to have the UNIQ...QINU string encased in #7f. Ref: Parser.php lines 132 & 133.