Jump to content

Module talk:Template invocation

Page contents not supported in other languages.
From Wikipedia, the free encyclopedia

Lua error: attempt to compare string with number.

[edit]

At Template:Toolbar/testcases and Template:3x/testcases test cases fail with this backtrace:

Backtrace:

    [C]: in function "sort"
    Module:Template_invocation:107: ?
    (tail call): ?
    Module:Template_test_case:140: in function "getInvocation"
    Module:Template_test_case:642: in function "?"
    Module:Template_test_case:663: ?
    [C]: in function "tostring"
    Module:Template_test_case:786: ?
    (tail call): ?
    mw.lua:518: ?
    [C]: ?

The issue seems to be caused by template invocation, in which a positional parameter is {{=}} and at least one named parameter is present. I've added test14_equals_sign_parameter to Module:Template test case/testcases to demonstrate the issue. —⁠andrybak (talk) 14:25, 19 May 2020 (UTC)[reply]

I haven't looked at what this module does or how it's used but the cause of the error is simple. A loop at line 104 uses pairs(invArgs) to put each key (parameter name) into the invArgs_list array. That will include numbers like 1 if the first unnamed parameter is entered, and strings like the names of any named parameters. Line 107 then fails because it cannot sort a mixture of numbers and strings. Someone would have to work out what the module wants to do at that point (why is it sorting the parameters names?) and decide what should happen to numbered parameters. Perhaps they should be omitted, or converted to strings. Or, add a custom sort routine to put the numbers before the strings. Ping me if help is wanted with implementing any of this after deciding what is wanted. Johnuniq (talk) 23:39, 19 May 2020 (UTC)[reply]
Johnuniq, at line 95, the module tries to guess if something that looks like 1=foo=bar was passed to the template:
::		if type(v) == 'string' and v:find('=', 1, true) then
::			-- Likely something like 1=foo=bar, we need to do it as a named arg
::			break
::		end
::
My guess is that this logic breaks when characters on the left of equals sign are not a valid parameter name or index. For example, two opening curly braces, as is the case with transclusion of {{=}} as a template. —⁠andrybak (talk) 00:13, 20 May 2020 (UTC)[reply]
No, {{=}} would be expanded before the module sees it. I was trying to avoid taking the time to work out how it's used but I'll look later. The questions I posed above are what need to considered. Regardless of how the template should be used, it should not break with this error if someone uses a mixture of unnamed and named parameters. Johnuniq (talk) 00:31, 20 May 2020 (UTC)[reply]
Johnuniq, sorry for the confusion, I should have been more clear. What I'm trying to say is that {{=}} is a corner case. If the module had issues with just a mixture of unnamed and named parameters, every other /testcases page would have been broken. —⁠andrybak (talk) 00:51, 20 May 2020 (UTC)[reply]
What I said is correct. If you have an example of a template that appears to contradict my assessment, please identify it. The explanation would be that the code I looked at (just a couple of lines around line 95) does not receive the numbered parameters. My first attempt to work out what this module is for failed. How does this module end up in lots of articles, for example Alan Garner? Is there a particular template that is responsible for most of those? {{Toolbar}}? Very briefly, why is this module needed for toolbar? Johnuniq (talk) 01:48, 20 May 2020 (UTC)[reply]

The code seems somewhat broken to me. I would fix it but omg it's used in so many places and I haven't got a clue why it is invoked in articles. For a lol, see Module talk:Template invocation/testcases which apparently has been displaying "Error: attempt to compare string with number" for a long time. Johnuniq (talk) 03:42, 20 May 2020 (UTC)[reply]

@Andrybak: OK I got courageous and fixed the module anyway. Please check it out. Johnuniq (talk) 04:05, 20 May 2020 (UTC)[reply]
A mystery explained with a mystery: the reason the module is used at Alan Garner is that it uses {{postnominals}} and even "{{postnominals}}" (with no parameters) calls Module:Template invocation. Johnuniq (talk) 04:50, 20 May 2020 (UTC)[reply]

Editor-hostile wikitext

[edit]

The module is currently producing "editor-hostile wikitext" by not adding spaces between the parameters. Please add a space at line Module:Template_invocation#L-116:

ret[#ret + 1] = ' ' .. seps.pipe

(an alternative solution by changing pipe = '|', to pipe = ' |', at Module:Template_invocation#L-81 would probably be less robust, since pipe is used for unnamed parameters as well, but some such templates don't trim whitespace from their arguments). — Mikhail Ryazanov (talk) 20:56, 9 February 2024 (UTC)[reply]

 Done * Pppery * it has begun... 23:23, 9 February 2024 (UTC)[reply]
Thank you, seems to work better now. I've updated the test cases accordingly. — Mikhail Ryazanov (talk) 00:25, 11 February 2024 (UTC)[reply]

I've stumbled upon a minor glitch caused by Special:Diff/1205562670. At Template:Myprefs/testcases#Notifications, the wikitext is shown with an extra space before the pipe in |check=:

{{Myprefs|Notifications|Notify me about these events |check=Page links}}

instead of:

{{Myprefs|Notifications|Notify me about these events|check=Page links}}

This is significant, because for unnamed positional parameters the whitespace isn't stripped. Compare: {{tl|x1}}{{x1}} vs {{tl| x1 }}{{ x1 }}. The extraneous space might confuse editors who are copy-pasting from testcases.

I propose to fix it by not adding a space for the first named parameter. A hacky implementation via variable maybeSpace in sandbox: Special:Diff/1205562670/1234263149. Tested at Special:Diff/1234262869. —⁠andrybak (talk) 12:44, 13 July 2024 (UTC)[reply]

Courtesy pings: Pppery, Mikhail Ryazanov. —⁠andrybak (talk) 12:47, 13 July 2024 (UTC)[reply]
Fine with me. * Pppery * it has begun... 15:46, 13 July 2024 (UTC)[reply]
It's a tolerable workaround, but in principle, templates that use positional parameters must use {{trim}} in cases where leading/trailing spaces don't have any functional purpose (besides readability) but can break the result. — Mikhail Ryazanov (talk) 20:23, 13 July 2024 (UTC)[reply]

Title clash in a few edge cases

[edit]

Currently, the "name" function returns the wrong result in three edge cases. Two of these are relatively straightforward to fix, but the third is more tricky:

  1. A page name like "Template:User:Theknightwho" should not return "User:Theknightwho", but instead should remain "Template:User:Theknightwho".
  2. The function should throw an error if it receives a title with an interwiki prefix (e.g. {{fr:foo}}) or one which starts with "#" (e.g. {{#foo}}), since both of these generate valid title objects, but neither can be used with template invocations.
  3. (Harder to fix): when a template name overlaps with that of a magic word, the "Template:" prefix is required in order to disambiguate it: e.g. {{Template:!}} or {{Template:PAGENAME:foo}}.

I've done a full implementation at wikt:Module:template parser#L-218, but it relies on loading data for point 3, which might not be desirable to import to Wikipedia. However, points 1 and 2 are pretty simple to deal with. I've drafted a new version of the function below, incorporating fixes for both of them:

function p.name(title)
	if type(title) == 'string' then
		title = mw.title.new(title)
		if not title or #title.prefixedText == 0 or #title.interwiki > 0 then
			error("invalid title in parameter #1 of function 'name'", 2)
		end
	elseif type(title) ~= 'table' or type(title.getContent) ~= 'function' then
		error("parameter #1 of function 'name' must be a string or a mw.title object", 2)
	end
	if title.namespace == 10 then
		local text = title.text
		local check = mw.title.new(text, 10)
		-- Exclude the prefix, unless we have something like "Template:Category:Foo", which can't be abbreviated to "Category:Foo".
		return check and mw.title.equals(title, check) and text or title.prefixedText
	elseif title.namespace == 0 then
		return ':' .. title.prefixedText
	else
		return title.prefixedText
	end
end

Theknightwho (talk) 20:07, 31 August 2024 (UTC)[reply]