Page MenuHomePhabricator

getAllExpandedArguments needs to be order preserving
Closed, InvalidPublic

Description

getAllExpandedArguments, which is called when one uses pairs( frame.args ), does not process the arguments in order. Under at least one circumstance this breaks existing behavior.

Consider:

{{my_template

top = <ref>Some Ref</ref>
bottom = <references />

}}

In order for this to process correctly, it is required that the argument for top= be parsed before the argument for bottom=. If they are parsed out of order, then the references tag will render as empty because no refs have yet been loaded.

In the current parser, in order processing is reliably performed, but it appears that Lua getAllExpandedArguments can process these arguments in either order. The order used appears to be stable but unpredictable, so that for a given template it will consistently either behave correctly or incorrectly but similarly constructed templates can work differently.

Simply running a for loop over pairs( frame.args ) and exporting the keys will show that the ordering of the keys bears no apparent relationship to the ordering of the input.

A consequence of this bug is discussed at:
http://en.wikipedia.org/wiki/Template_talk:Navbox#Bugs


Version: unspecified
Severity: normal

Details

Reference
bz46566

Event Timeline

bzimport raised the priority of this task from to Needs Triage.Nov 22 2014, 1:19 AM
bzimport added a project: Scribunto.
bzimport set Reference to bz46566.
bzimport added a subscriber: Unknown Object (MLST).

getAllExpandedArguments does process arguments in order.

The linked discussion complains that the following parses list1 before below:

{{Navbox with columns
|navbar = plain
|state = plain
|title = Navbox with columns
|list1 = Item<ref group="b">aaa</ref>
|below = Reflist: {{reflist|group="b"}}
}}

This is expected, considering that [[Template:Navbox with columns]] simply calls [[Template:Navbox]] and passes {{{below|}}} to that template before {{{list1}}}. Template:Navbox is the one that has the #invoke, so its argument order is the order that is used by getAllExpandedArguments in pairs( frame:getParent().args ).

The reason this sort of thing worked with the old parserfunction-based templates is that the old version of Template:Navbox itself processed its arguments in the expected order rather than in whatever order they were passed to the template.