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

Wikimedia Bugzilla is closed!

Wikimedia has migrated from Bugzilla to Phabricator. Bug reports should be created and updated in Wikimedia Phabricator instead. Please create an account in Phabricator and add your Bugzilla email address to it.
Wikimedia Bugzilla is read-only. If you try to edit or create any bug report in Bugzilla you will be shown an intentional error message.
In order to access the Phabricator task corresponding to a Bugzilla report, just remove "static-" from its URL.
You could still run searches in Bugzilla or access your list of votes but bug reports will obviously not be up-to-date in Bugzilla.
Bug 3896 - Nested extension calls inside templates cause incomplete rendering
Nested extension calls inside templates cause incomplete rendering
Product: MediaWiki
Classification: Unclassified
Templates (Other open bugs)
PC Linux
: Normal normal with 1 vote (vote)
: ---
Assigned To: Nobody - You can work on this!
Depends on:
  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: ---

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

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

The following extension:
$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)"; 


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

And the following Wikitext in ATemplate:

Renders Test_Page as:
Here is the test:

outer text 1

inner text 1



inner text 2

outer text 2

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:
removing the calls to inner, it renders correctly as:
Here is the test:

outer text 1

inner text 1

(inside) (inside)

inner text 2

outer text 2

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
{{: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:
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
    $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

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.