Last modified: 2010-05-15 15:38:11 UTC

Wikimedia Bugzilla is closed!

Wikimedia migrated from Bugzilla to Phabricator. Bug reports are handled in Wikimedia Phabricator.
This static website is read-only and for historical purposes. It is not possible to log in and except for displaying bug reports and their history, links might be broken. See T5896, the corresponding Phabricator task for complete and up-to-date bug report information.
Bug 3896 - Nested extension calls inside templates cause incomplete rendering
Nested extension calls inside templates cause incomplete rendering
Status: RESOLVED FIXED
Product: MediaWiki
Classification: Unclassified
Templates (Other open bugs)
1.5.x
PC Linux
: Normal normal with 1 vote (vote)
: ---
Assigned To: Nobody - You can work on this!
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2005-11-06 19:21 UTC by E Feinstein
Modified: 2010-05-15 15:38 UTC (History)
0 users

See Also:
Web browser: ---
Mobile Platform: ---
Assignee Huggle Beta Tester: ---


Attachments
The extension file (2.36 KB, text/plain)
2005-11-06 19:22 UTC, E Feinstein
Details
Test wikitext (Test_page) (148 bytes, text/plain)
2005-11-06 19:24 UTC, E Feinstein
Details
Test ATemplate (34 bytes, text/plain)
2005-11-06 19:25 UTC, E Feinstein
Details

Description E Feinstein 2005-11-06 19:21:05 UTC
A form of extension call inside a template will cause another extension not to
be called.  Instead, an intermediate of the wikitext is rendered.

Version info:
MediaWiki: 1.5.2
PHP: 4.3.10-16etch1 (apache2handler)
MySQL: 4.1.14-Debian_6-log

Example:
The following extension:
<code>
<?php
$wgExtensionFunctions[] = "wfTestExtension";

function wfTestExtension() {
	global $wgParser;

	$wgParser->setHook( "inner", "innerHook" );
	$wgParser->setHook( "inside", "insideHook" );
}


function innerHook( $input, $argv  ) {
	# set a variable
	global $wgOut;

	$output = $output.$wgOut->parse($input, false);
		
	return $output;
}

function insideHook( $input, $argv  ) {
	return "(inside)"; 
}

?>
</code>

And the following wikitext (in a page called Test_Page):
<code>
Here is the test:
<p>outer text 1</p>
<inner>
<p>inner text 1</p>
<inside></inside>
{{:ATemplate}}
<p>inner text 2</p>
</inner>
<p>outer text 2</p>
</code>

And the following Wikitext in ATemplate:
<code>
<inner>
<inside></inside>
</inner>
</code>

Renders Test_Page as:
<pre>
Here is the test:

outer text 1

inner text 1

NaodW29-inside593e7feb7eece2e700000001

(inside)

inner text 2

outer text 2
</pre>

Note that it's the <inside></inside> call in Test_Page that is failing.  The one
in ATemplate works correctly.

IF ATemplate is changed to:
<code>
<inside></inside>
</code>
removing the calls to inner, it renders correctly as:
<pre>
Here is the test:

outer text 1

inner text 1

(inside) (inside)

inner text 2

outer text 2
</pre>

So, the nested call to inner inside a template fails.

Nested extension calls outside a template never work because the inner instance
of the /inner tag will close the outer call to inner.
Comment 1 E Feinstein 2005-11-06 19:22:58 UTC
Created attachment 1048 [details]
The extension file
Comment 2 E Feinstein 2005-11-06 19:24:09 UTC
Created attachment 1049 [details]
Test wikitext (Test_page)
Comment 3 E Feinstein 2005-11-06 19:25:00 UTC
Created attachment 1050 [details]
Test ATemplate
Comment 4 Brion Vibber 2005-11-06 20:04:15 UTC
I don't really understand the question that's being asked, or 
what you're trying to accomplish.
Comment 5 E Feinstein 2005-11-06 21:22:38 UTC
The extension I'm trying to write is a variation on page-specific variables. 
You could then so something like this:

<set flag="x">   <-- sets a given flag to true
<flag name="x"></flag>  <-- returns the value of the flag
{{:Template_with_conditional_text}}  <-- this template has a conditional
expression in it that depends on the value of flag x.  It should also be able to
reset the value of the flag and call other templates
</set>
{{:Template_with_conditional_text}}  <-- this template has a conditional
expression in it that depends on the value of flag x and will output different
text than the first time it was called

In the test-case, inner is analogous to "set."  And "inside" is analogous to
"flag."  But, any time "flag" ("inside" in the test case) is called from inside
a nested "set" call in the template ("inner", in the test case), one instance of
"flag"/"inside" is left as a MediaWiki internal representation of the call.

I claim that I should never see text resembling:
NaodW29-inside593e7feb7eece2e700000001
It's some kind of intermediate form of an extension call generated in
Parser.php.  And, that's a bug.

The attached test-case is a very simple example of the phenomenon that is
independent of anything I'm trying to accomplish.  But, it does demonstrate the
effect without the complication of the rest of my code.
Comment 6 Brion Vibber 2005-11-06 23:57:57 UTC
Nested extensions are really not something the current parser expects or 
is designed to work with, so by using them you're likely to have all 
kinds of trouble. (Consider software other than MediaWiki; MediaWiki 
text is not meant to be a programming language.)

Register your hooks in the other order, so the <inside> bits are 
replaced before the <inner> bits:

$wgParser->setHook( "inside", "insideHook" );
$wgParser->setHook( "inner", "innerHook" );
Comment 7 E Feinstein 2005-11-07 00:35:57 UTC
I tried reversing the order and it works in this case.  I am evaluating
MediaWiki because it has a long list of other features that I want (good
interface, full UTF-8 and multilingual support).  If I can extend it to do what
I want it to do, I'll use it, if not, I'll use the software that will come
closest to what I want it to do.  Thanks.
Comment 8 Piotr Biegański 2006-01-03 12:12:15 UTC
I wrote very simple extension rendering coloured text inside extension tags.
It worked correctly until I enabled parsing internal text.
I found this bug when using ext in templates, but observed also without them.

Extension file: Test.php
  <?php
    $wgExtensionFunctions[] = "wfTestExtension";
    function wfTestExtension() {
      global $wgParser;
      $wgParser->setHook( "test", "renderTest" );
    }
    
    function renderTest( $input, $params ) {
      global $wgOut;
      $result = "<span style=\"color: red\">";
      $result .= $wgOut->parse( $input, false );
      $result .= "</span>";
      return $result;
    }
  ?>

Two wiki pages defined as:
  Sandbox          = {{Template:Sandbox}} aka <test>PLAYGROUND</test>
  Template:Sandbox = <test>SANDBOX</test>

Output on "Sandbox" page:
  SANDBOX aka UNIQ23f6a50866512e57-test21156fe8641c796200000001

Details:
  http://meta.wikimedia.org/w/index.php?title=MediaWiki_extensions_FAQ#Templates_with_extension_tags
Comment 9 Brion Vibber 2006-06-04 00:38:38 UTC
This works fine on trunk if you use the parser parameter 
passed to your extension hook. See Cite.php in the Cite 
extension for an example.

Note You need to log in before you can comment on or make changes to this bug.


Navigation
Links