Wikipedia talk:Lua/Archive 9

Latest comment: 4 years ago by ProcrastinatingReader in topic Db-multiple
Archive 5Archive 7Archive 8Archive 9Archive 10Archive 11Archive 12

Search cities

Template ( https://ru.wikipedia.org/wiki/Шаблон:Население https://ru.wikipedia.org/wiki/Модуль:Statistical ) provides information for the users in numbers and graphs about the population. On the one hand, we have population censuses and data for different years. On the other hand, we call this data through a template simply by specifying the name of the city. But there are many thousands of cities. Working through lua-modules, we made a unique hash of the name of the city and, by a unique hash, we further searched for numbers on the population. But these are >60 tables of 3000 elements ( https://ru.wikipedia.org/wiki/Шаблон:Население/STA-061 ) for these unique hashes. lua mw.loadData results in maximum use of the amount of memory allocated for lua. The hash was placed in the templates ( https://ru.wikipedia.org/w/index.php?title=Модуль:Statistical&diff=83973924&oldid=82885634 ) and searched through the switch and expandTemplate. From 4th to 7th of June, 2019, we experienced problems that appeared apparently somewhere on the server side, because before and after this period it again appears without errors. Probably the slow work of a large switch results in maximum use of the work time allocated for lua. And further template calls for the public return the red text of the error "lua limit reached". Thus, it seems that we are somewhere on the verge of the possibility of the module / templates working. Could there be a faster or more practical way to work with such a large amount of data? --Sunpriat (talk) 11:02, 11 June 2019 (UTC)

most likely i did not really understand what is it you are doing and why, but for what i could figure, it looks bizarre.
  1. why do you even need to create a hash? each wikipedia article already has a "unique identifier", which we call wikidata item ("Q12345678" and such). it makes much more sense to me to use this identifier than your "hash".
  2. in general, the natural place to keep "large amount of statistical data" is wikidata. keeping it locally in lua modules in ruwiki, to be loaded with loadData() would only makes sense if wikidata did not exist (maybe this was started before wikidata existed).
    • in addition to removing the limitation of large data handling, the real advantage of keeping your statistical data in wikidata, is that _other_ projects, in addition to ruwiki will be able to enjoy the fruit of your labor, which is the true wikipedia spirit. the flip side, is that once other projects find it useful, they will further enrich wikidata with same type of stats for more cities around the world, so ruwiki will be able to show those graphs for articles where you did not harvest the stats yourselves.
  3. even if all i wrote above is junk, i suggest you switch your "hash calculation" from roll-it-yourself lua code to the mw.hash library, which supports close to 50 different hashing algos, including md2, md4 md5, sha1 and more than 40 others.
tl;dr: i probably did not understand what you are doing/trying to do and why, but inasmuch as i did, you should write some code to upload the data from ruwiki to wikidata, and teach your templates and graphs to read it from there.
peace - קיפודנחש (aka kipod) (talk) 17:52, 11 June 2019 (UTC)
I don't fully understand how the module works, but in answer to your question about whether the {{#switch:}} parser function in ru:Шаблон:Население/STA-061 uses Lua resources (if I am not misunderstanding), it does not. Lua resources are only used by invocations of modules. Regardless of how much time the {{#switch:}} parser function takes, the Lua invocations are allowed to run for up to 10 seconds. — Eru·tuon 05:00, 12 June 2019 (UTC)

Template:Calendar - Request to Lua-ize

This will probably be a Herculean task, but I'm hoping someone can help me with this: Can someone possibly get {{Calendar}} "Lua-ized" via a module at Module:Calendar? Asking since ... something I'm trying to do ran across expensive call template include size issues. So ... I'm really hoping this can be accomplished. Steel1943 (talk) 00:27, 29 June 2019 (UTC)

Not expensive, but rather a template include size problem. You can see the parser profile data for User:Steel1943/sandbox/sandbox2/template by editing that page, and then previewing. At the bottom, click the 'Parser profiling data' link. Profile data are also in the page html source; search for 'NewPP limit report'.
I haven't spent any time with that template but I can probably noodle out how to convert it to a module if no one else does it first.
Trappist the monk (talk) 00:45, 29 June 2019 (UTC)
@Trappist the monk: And there you go; I just learned today that there's more than "expensive" issues when it comes to template calls. If you can figure out how to write that module, it would be greatly appreciated, considering multiple uses of {{Calendar}} in that form could probably benefit many of the discussion boards. Steel1943 (talk) 00:49, 29 June 2019 (UTC)
I wrote Module:Current events calendar back in 2014; that might be of use in converting this template. Even better, we could write a generalised calendar widget module and rewrite Module:Current events calendar to use that. I would advise against naming it Module:Calendar, by the way - it clashes with the module over at Commons, which has caused problems in the past when people try to import modules to other wikis. — Mr. Stradivarius ♪ talk ♪ 09:12, 29 June 2019 (UTC)
So the generalized calendar widget would render a basic month or a basic year calendar? Does the widget define the calendar's style or is that supplied in the call to the widget? Does the call to the widget include a table of links; some specialized prefix / suffix keywords that apply to all dates; links for month / year / next month (year) / previous month (year) / header & footer text (links) / other properties that I haven't thought of yet?
Are there other calendar templates that might take advantage of / influence this widget?
Too bad about Module:Calendar – that is just the right name for a module that implements {{calendar}}. Module:Calendar widget? Continue this discussion there?
Trappist the monk (talk) 10:52, 29 June 2019 (UTC)
Found some other calendar templates in Category:Calendar templates, though from a brief look, it seem it would be hard to make them fit: {{ISOCALENDAR}}, {{Republican Calendar}}, {{List of calendars}} and various Olympic templates at Category:Olympics calendar templates such as {{1952 Winter Olympics calendar}}. --Gonnym (talk) 12:09, 29 June 2019 (UTC)
{{ISOCALENDAR}} has form and styling vaguely similar to {{calendar}} and to Module:Current events calendar so could be a candidate for the widget.
To add to my list above: highlight today's date / some special date / range of dates / all of a specific weekday?
Trappist the monk (talk) 12:50, 29 June 2019 (UTC)
Also: use template styles instead of inline css? If a template using the widget needs special styling, pass in that template's template styles?
Trappist the monk (talk) 13:34, 29 June 2019 (UTC)
I do not see it as problematic that Commons has a module named similar. It's not our problem until such time as something using that module is imported, and when it is, we can maintain a trivial fork here. --Izno (talk) 13:36, 29 June 2019 (UTC)
@Izno: The problem comes when a smaller Wikipedia, let's say Welsh or Azerbaijani, wants to use a template from Commons that calls c:Module:Calendar; and then wants to also use the enwiki template {{Calendar}}. If we use a more qualified name for our module, then they can import everything without having to create a fork on their own language Wiki. My experience is that such forks are rarely trivial for me to do for them in either Welsh or Azerbaijani, or for them to do if they have no Scribunto programmers. --RexxS (talk) 13:49, 29 June 2019 (UTC)
Anyone know how easy it is to rename a page on commons? From the description of that module, c:Module:Convert date seems more correct for it. --Gonnym (talk) 14:16, 29 June 2019 (UTC)
I strongly agree with Izno. Modules should be given names without regard to what is happening on other wikis. Additionally, I don't see the value in having one module having a name that doesn't conflict with Commons when there are already two other modules with conflicting names between the English Wikipedia and commons. * Pppery * ... ... ... 23:19, 29 June 2019 (UTC)

I've made a start with Module:Calendar widget, Template:Calendar widget and Template:Calendar widget/styles.css. There is some testing of the module at Module talk:Calendar widget/Testing. I threw in a couple of exported functions that check for a leap year and return what day of the week a particular date is. There's virtually no inline styling in the module, but all of the tables, rows, headers and data cells have a class set that can be styled via the template's template styles. I still have to implement most of the parameters available for Template:Calendar, but I'll have another look tomorrow if I get a chance. Please feel free to hack at it if you're interested. Cheers --RexxS (talk) 00:26, 30 June 2019 (UTC)

2000
January
SuMoTuWeThFrSa
      1
2345678
9101112131415
16171819202122
23242526272829
3031     
February
SuMoTuWeThFrSa
  12345
6789101112
13141516171819
20212223242526
272829    
March
SuMoTuWeThFrSa
   1234
567891011
12131415161718
19202122232425
262728293031 
April
SuMoTuWeThFrSa
      1
2345678
9101112131415
16171819202122
23242526272829
30      
May
SuMoTuWeThFrSa
 123456
78910111213
14151617181920
21222324252627
28293031   
June
SuMoTuWeThFrSa
    123
45678910
11121314151617
18192021222324
252627282930 
July
SuMoTuWeThFrSa
      1
2345678
9101112131415
16171819202122
23242526272829
3031     
August
SuMoTuWeThFrSa
  12345
6789101112
13141516171819
20212223242526
2728293031  
September
SuMoTuWeThFrSa
     12
3456789
10111213141516
17181920212223
24252627282930
October
SuMoTuWeThFrSa
1234567
891011121314
15161718192021
22232425262728
293031    
November
SuMoTuWeThFrSa
   1234
567891011
12131415161718
19202122232425
2627282930  
December
SuMoTuWeThFrSa
     12
3456789
10111213141516
17181920212223
24252627282930
31      

So I broke it. I know how it's broken but am at a loss to know why.

I had thought to use the Scribunto HTML library because it seemed to me that support for variations in styling and whatever other sorts of options that might be wanted could more easily handled by that library. I haven't used the HTML library before so my own naivete might be mostly to blame for the broken code.

As you can see the individual monthly calendars aren't top-aligned as they should be. The style is properly included but the <tr> tag that holds it is immediately closed:

<table class="ycal"><tr class="ycalhdr"><th class="ycal" colspan="4">2000</th></tr><tr class="ycal" style="vertical-align:top"></tr><td class="ycal">

For comparison, here is the original (stretched out to make it easier to compare):

<table class="ycal"><tr class="ycalhdr"><th class="ycal" colspan="4>2000</th><tr class="ycal" style="vertical-align:top;"><td class="ycal">

I notice that the original is, I think, missing a </tr> after the <th>...</th> tag.

What did I do wrong? Is it bad that I have only made this change to displayyear() and not to displaymonth()?

The original code remains but has been commented out and there is an mw.log() that dumps the html output to the debug console log.

Trappist the monk (talk) 00:51, 1 July 2019 (UTC)

The vertical-align:top needed to be against the td tag rather than the tr tag. I've also put it in Template:Calendar widget/styles.css instead of in the module code. -- WOSlinker (talk) 05:57, 1 July 2019 (UTC)
Thanks. That appears to fix the issue. But, wait, ... the html is still broken:
<table class="ycal"><tr class="ycalhdr"><th class="ycal" colspan="4">2000</th></tr><tr class="ycal"></tr><td class="ycal">
And shouldn't <tr style="vertical-align:top"> apply to the enclosed <td>...</td> tags?
So I guess my question remains: What am I doing wrong?
Trappist the monk (talk) 10:20, 1 July 2019 (UTC)
Hopefully this change fixes that issue. -- WOSlinker (talk) 10:37, 1 July 2019 (UTC)
Apparently it does:
<table class="ycal"><tr class="ycalhdr"><th class="ycal" colspan="4">2000</th></tr><tr class="ycal"><td class="ycal">
Excellent! But, can you please explain to me why that works?
Trappist the monk (talk) 11:02, 1 July 2019 (UTC)
Before, you were adding both the tr and td tags to the year_cal object (which is the table tag). If you save a reference to the tr tag in a new object then you can add the td tag to that object instead of the year_cal object. -- WOSlinker (talk) 11:10, 1 July 2019 (UTC)
Thank you but, sorry, I'm lost. If the assignment in local year_row = year_cal makes year_row a new object, how does year_cal know anything about what gets added to year_row? This suggests to me that year_row and year_cal are not separate objects but are 'pointers' or 'references' to the same 'thing'. If they are 'pointers' or 'references' then that explains why everything that got added to year_row is present at the end when return tostring (year_cal). But that doesn't explain why it is necessary to indirectly add the <td>...</td> tags via year_row.
Trappist the monk (talk) 11:40, 1 July 2019 (UTC)
Yes, the new variable year_row is a pointer. -- WOSlinker (talk) 12:03, 1 July 2019 (UTC)
Ok, since year_row is a pointer, why is it necessary?
Trappist the monk (talk) 12:25, 1 July 2019 (UTC)
Not really my area of expertise, but I think when you add a new tag against an object, it closes the previously added tag (that was added to that object). -- WOSlinker (talk) 13:03, 1 July 2019 (UTC)
Because calling year_cal:tag('tr') year_cal:tag('td') just adds tags as direct children of year_cal. Calling local year_row = year_cal:tag('tr') year_row:tag('td') adds a tr tag to year_cal, returns it, saves a reference to it in the local variable (because the tag method returns a new object for the tag that was created), and using this reference adds a td tag to it rather than to year_cal. — Eru·tuon 13:36, 1 July 2019 (UTC)
I think that I understand what you wrote but I'm struggling to find the words that describe my continuing confusion.
Trappist the monk (talk) 14:42, 1 July 2019 (UTC)
At about the time that Editor WOSlinker was making this post I was wondering if the right and proper thing to do would be to put the several <td>...</td> tags that are required for each row into :wikitext() because that is how (as I understand it) content is meant to be added to a tag. So I hacked a function that does the necessary work to create <td>...</td> tags and called it from year_cal:wikitext(). It works without confusing indirection.
This is implemented in the current version of the module. Because this widget creates a bunch of tables perhaps it is possible to generalize add_td_tags() so that it can be used more broadly than it is now. I'll think on that.
Trappist the monk (talk) 14:42, 1 July 2019 (UTC)

Is it possible in a template to extract data from a module rather than a function?

For example, if module was:

local str = "Hello World!"
local p = {["string"] = str};
p.hello = function(frame)
    return str
end

return p

and the template code {{#invoke:moduleName|string}} returned Hello World!. Or do I have to create a function if I want to achieve that? —⁠andrybak (talk) 08:34, 5 July 2019 (UTC)

A module may have a module-wide “global” variables although they are (rather jarringly) declared with local outside functions. The main concern is performance – too much global stuff slows execution down; it is better to resort to require(modulename) in the case where heavy initialized data are desirable. Incnis Mrsi (talk) 09:56, 5 July 2019 (UTC)
The question concerns whether X in {{#invoke:moduleName|X}} has to be a function name, or whether it could be a code (such as "string") to get the code's value (such as "Hello World!"). The answer is yes it can be a code, but it's pretty ugly and involves setting a metatable on p such that X is interpreted at runtime. A lot less hair would be lost if the call were {{#invoke:moduleName|get|X}} where the function get returns the value for X. See Module:Data for how magic metatable code can be written. Johnuniq (talk) 10:43, 5 July 2019 (UTC)

Question from a newbie

Hello, I have few connoissances into Lua. I have (one) (or multiple words) into a given string. Example : <CDG LAX JFK> (string without the < and the >) I would need this string transformed into %22CDG%20LAX%20JFK%22 so that this being understandable by a sparql query. I have written a short code but it doesn't come the fashion I need. Any tip would be greatly appreciated. --Bouzinac (talk) 20:16, 23 July 2019 (UTC)

Can the URI library help you here? --Gonnym (talk) 20:18, 23 July 2019 (UTC)
Thanks. I was building this function
local p = {}
s=frame.args[1]
function p.recode(frame) 
    return "%22".. s:gsub(" ","%20").. "%22"
end
return p
Where am I wrong ?
OK, got it with
local p = {}

function p.recode(frame) 
	return "%22" .. mw.uri.encode(frame.args[1],"PATH") ..  "%22"
end
return p
 :) --Bouzinac (talk) 20:43, 23 July 2019 (UTC)
No, it does not work when multiples code, works only when one code. I need a transformation being string other_string other_string be "string" "other_string" "other_string"
and then be urlencoded. Bouzinac (talk) 20:52, 23 July 2019 (UTC)
If I understand you right, maybe something like this would work:
local function transform(s)
	return mw.uri.encode(s:gsub("%S+", '"%1"'), "PATH")
end

function p.transform(frame)
	return transform(frame.args[1])
end
It encloses sequences of non-ASCII-whitespace characters in quotes and then percent-encodes the string. — Eru·tuon 21:13, 23 July 2019 (UTC)
That's exactly what I wished. Many thanks --Bouzinac (talk) 21:18, 23 July 2019 (UTC)

mw.ext.ParserFunctions.expr

I'm trying to use the ParserFunctions library in lua for it's trunc() calculation, but Help:Extension:ParserFunctions has no documentation at all how its used other than mw.ext.ParserFunctions.expr. The most I was able to get is mw.ext.ParserFunctions.expr("trunc", value) but that gives me the error "Lua error: Expression error: Missing operand for trunc..". Any ideas? --Gonnym (talk) 07:43, 24 July 2019 (UTC)

Gonnym, i've made a task of the fact that this library is undocumented. phab:T228840TheDJ (talkcontribs) 08:52, 24 July 2019 (UTC)
Thanks! --Gonnym (talk) 18:29, 24 July 2019 (UTC)
Try this (untested).
local success, result = pcall(mw.ext.ParserFunctions.expr, 'trunc 1234.5678')
if success then
    -- result is the result
else
    -- result is error text
end
Johnuniq (talk) 08:16, 24 July 2019 (UTC)
That seems to work although I have no idea why, as mw.ext.ParserFunctions.expr('trunc 1234.5678') doesn't. --Gonnym (talk) 18:29, 24 July 2019 (UTC)
@Gonnym: are you sure? i didn't create a module to test it, but it did return 1234 in scribuntu debug console (open any module for edit, and type "=mw.ext.ParserFunctions.expr('trunc 1234.5678')" <Enter> in the debug console). peace - קיפודנחש (aka kipod) (talk) 18:53, 24 July 2019 (UTC)
Well, now it does work. No idea what I did differently before. I blame the hour. Also, thanks :)--Gonnym (talk) 19:23, 24 July 2019 (UTC)
oh, and the most intriguing question: why would anyone even want to call "mw.ext.ParserFunctions.expr" if what you want to do is "trunc"? why not ask lua directly?
local input = 1234.5678
local truncated = math.floor(input) -- returns the same as mw.ext.ParserFunctions.expr('trunc ' .. input)
input = '1234.5678' -- works for strings, too:
truncated = math.floor(input) -- still 1234: i guess math.floor is nice enough, and calls tonumber() for you, or something. JS behave similarly
-- math.floor will throw if the parameter is not "numberable", e.g. "bla", '', or nil. you can use pcall, or test directly:
local num = tonumber(input)
if num then -- safe: in lua, 0 evaluates to true
    truncated = math.floor(num)
else
-- do some error handling
end
i can't imagine what do you gain by calling mw.ext.ParserFunctions.expr, if what you want to do is trunc, unless the parameter passed to the template _is_ trunc 1234.5678 or or trunc(1234.5678). this looks a bit bizarre (why would the editor pass something like this as a parameter?), but i guess it's possible. peace - קיפודנחש (aka kipod) (talk) 19:34, 24 July 2019 (UTC)
I'm trying to convert a set of templates to lua, so the first step I was trying to do is just understand the code flow and get a simple version working. That template used the trunc function which was why I wanted that. I didn't spend time debugging all scenarios to see if it did anything else. I completely agree with you though, that using your suggested code would be a much better end-result. --Gonnym (talk) 20:10, 24 July 2019 (UTC)
I have converted a couple of complex templates by writing the logic in pseudocode, being careful to include all the tricky conditions that apply to template wikitext (like what #if really does). After I've got the pseudocode, I convert that to Lua and hope that testcases will detect problems. Some functions in Module:Math might be useful. Johnuniq (talk) 00:13, 25 July 2019 (UTC)

Arithmetic expressions as strings

I have an array of arithmetic expressions as strings and I need to do a calculation with an x value for the relevant one, however it can't do that with an arithmetic expression as a string. I'd like to avoid needing to do this as an if/else. Any ideas? Code below:

local function main(value1, value2)
	local arithmeticExpressionList = {
		[1] = " % 2 + 4",
		[4] = " / 2 % 2 + 2",
		[6] = " / 4 % 2 + 5",
		[9] = " / 8 % 2 + 5",
		[12] = " / 16 % 2 + 3",
		[14] = " / 32 % 2 + 8",
		[17] = " / 64 % 2 + 6"
	}

	local arithmeticExpression = arithmeticExpressionList[value1]
	if (arithmeticExpression) then
		value = value2 .. arithmeticExpression
		return value
	end
end

--Gonnym (talk) 06:51, 25 July 2019 (UTC)

A simpler example with the expected result would be helpful (or use this example if you want to show its evaluation). I can't tell if the items should be concatenated and then evaluated or what. And % is remainder? Essentially you have to write your own expression parser (which I have done for a special purpose, but definitely not recommended!), or use mw.ext.ParserFunctions.expr from the previous section. Johnuniq (talk) 07:31, 25 July 2019 (UTC)
For a given value1 of 1 and a value2 of 7: value = value2 .. arithmeticExpression should be the same result as value = 7 % 2 + 4. % is Modulo operation. --Gonnym (talk) 07:36, 25 July 2019 (UTC)
Thanks for the tip about using mw.ext.ParserFunctions.expr, that does work (with a small change from "%" to "mod"). --Gonnym (talk) 07:44, 25 July 2019 (UTC)
Works, but producers different results for some values. mw.ext.ParserFunctions.expr(48.. arithmeticExpressionList[17])) results in 6, while 48 / 64 % 2 + 6 results in 6.75. That said, the template that I'm working from also gives 6, so mw.ext.ParserFunctions.expr is at least consistent with that and produces the same results. --Gonnym (talk) 08:10, 25 July 2019 (UTC)
Lua's % is more like ParserFunctions.expr's fmod, FYI. At least for positive numbers. Anomie 13:28, 25 July 2019 (UTC)
Do the arithmetic expressions actually have to be strings? If not, this should work:
local function main(value1, value2)
	local arithmeticExpressionList = {
		[1] = function ( x ) return x % 2 + 4 end,
		[4] = function ( x ) return x / 2 % 2 + 2 end,
		[6] = function ( x ) return x / 4 % 2 + 5 end,
		[9] = function ( x ) return x / 8 % 2 + 5 end,
		[12] = function ( x ) return x / 16 % 2 + 3 end,
		[14] = function ( x ) return x / 32 % 2 + 8 end,
		[17] = function ( x ) return x / 64 % 2 + 6 end
	}

	local arithmeticExpression = arithmeticExpressionList[value1]
	if (arithmeticExpression) then
		return arithmeticExpression( value2 )
	end
end
Anomie 13:28, 25 July 2019 (UTC)

Lua pattern question

Hey, I can't see how to get an exact match. I am using [Cc]hess in a template, looking to get back only the full-word matches of " Chess " and " chess ", but I of course also get "duchess", "duchesses", "Chessie", etc. What pattern code returns only the selected characters when they are surrounded by spaces, and not part of a larger word? Thanks in advance. UnitedStatesian (talk) 12:53, 20 August 2019 (UTC)

try: %f[%a]([Cc]hess)%f[%A]
Trappist the monk (talk) 13:05, 20 August 2019 (UTC)
Thanks TTM, that worked perfectly. You are the MAN! UnitedStatesian (talk) 14:00, 20 August 2019 (UTC)
@Trappist the monk: for my own edification, why is the first %a lower case and the second %A uppercase? Does it matter? UnitedStatesian (talk) 03:49, 23 August 2019 (UTC)
Yes, it matters. Search for "frontier" at mw:Extension:Scribunto/Lua reference manual and see lua-users. %a matches all letters, while %A does the opposite (it matches all non-letters). Johnuniq (talk) 04:05, 23 August 2019 (UTC)
Please excuse the typo fix, Johnuniq, the reference manual is on mediawiki, not meta (I make that mistake myself all the time).
@UnitedStatesian: The frontier pattern "%f[%a]" matches the transition from non-letters to letters, so "%f[%a]chess" would match "chess" at the beginning of a word (including the beginning of a string). The frontier pattern "%f[%A]" matches the transition from letters to non-letters, so "chess%f[%A]" would match "chess" at the end of a word (including the end of a string). The pattern that Trappist gave you uses both frontier matches to isolate the word alone as a match. HTH --RexxS (talk) 14:01, 23 August 2019 (UTC)
Thanks, both! UnitedStatesian (talk) 14:13, 23 August 2019 (UTC)

InfoboxImage module broken?

some of the examples on Module:InfoboxImage aren't showing any image at all, and I don't know if it's just my laptop. I tried having a look at the source but I know absolutely nothing about code so I don't know what's wrong or how to fix it... Snizzbut (talk) 15:48, 30 September 2019 (UTC)

@Snizzbut: I see five examples with no image. Two have no image specified; two specify a placeholder image without the |suppressplaceholder=no flag, and one uses an image that doesn't exist. I think that's correct. Do you see more than five examples without images? Certes (talk) 15:54, 30 September 2019 (UTC)
@Certes: Thank you so much for your explanations... I foolishly assumed that a) all the examples would be of how to use the template correctly and b) that all the examples would use the same image to make comparing easier; I hope you can see how they looked broken to someone with those assumptions! ^^; (if each one had text explaining what it is demonstrating that would be extremely helpful imo, especially for non-technical people) — Preceding unsigned comment added by Snizzbut (talkcontribs) 21:56, 4 October 2019 (UTC)

Wikipedia pages' access code

After mastering "hello world" my next stepping stone is code to get information for a given URL (PageSize for starters). Can some good soul turn my head in the right direction? TiA Vitosmo

PS comparable functions to wikitext have a blank when it comes to Pagesize (talk) 08:23, 9 October 2019 (UTC)
That's a bit of a jump, but you need to use the title object for article properties. Look through https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Scribunto_libraries for a description. There are some examples at User:RexxS/GCI. I think number 6 does the libraries. --RexxS (talk) 08:43, 9 October 2019 (UTC)
whenever i write yet another hello world code, i get reminded I have done this before. The same (I hope) for the suggested objects and classes;) (Fortran, PL I/opt, Ratfor,cobol, c, R ... c# dyno). THX so much! Vitosmo (talk) 18:33, 9 October 2019 (UTC)

Help for debugging: Module:SimpleDebug

Because I'm improving a fairly complex module (more than two thousand lines of code). I created this module to make easy the debugging of any other module, because the Debug console is not always useful enough.

Also I added a new chapter: Help:Lua_debugging#How_debug to explain the possibilities of debugging. Maybe it would be interesting to improve and/or correct it (since my English level is intermediate).

--Jmarchn (talk) 21:12, 22 October 2019 (UTC)

Ghost references

I'm not exactly sure what is going on, so I created a simplified example. I start with the base full table in User:Frietjes/l which transcluded in User:Frietjes/l1, User:Frietjes/l2, and User:Frietjes/l3. The problem appears in User:Frietjes/l1 which has an efn (in the ghost references section) that does not appear in the article. I think I have isolated it to the tracking, since if I turn the tracking off, I get User:Frietjes/l3 which doesn't have any ghost references. any idea how to get the tracking to work without showing the ghost references? feel free to make changes to Module:Sandbox/Frietjes and/or Module:Sports table/argcheck/sandbox if you have ideas on how to fix it. Frietjes (talk) 17:45, 1 November 2019 (UTC)

@Frietjes: Module:Sandbox/Frietjes seems to generate part of the table, showing up to four teams above and below the named team, then (without |notracking=) add notes for the whole table, including one for Ipswich who don't make the table due to finishing more than four places behind Arsenal. Certes (talk) 18:32, 1 November 2019 (UTC)
Certes, yes, that's what the module does. I have isolated the issue further by simplifying the code. as you can now see in Module:Sandbox/Frietjes the only difference between User:Frietjes/l1 and User:Frietjes/l3 is that User:Frietjes/l1 has a "no action" loop over all the args, where User:Frietjes/l3 only observes the args used to generate the table. so, here is my question: Is there a way to loop over all the keys in the args without generating these ghost references? I would like to be able to validate the input, but it's unfortunate that observing the args changes the output! The odd thing is that Module:Arguments seems to be looping over all the args, but doesn't seem to have the same problem. Frietjes (talk) 17:18, 3 November 2019 (UTC)
@Frietjes: It doesn't need a loop. Any access to the Ipswich text argument, e.g. local unused = args.text_IPS, causes the footnote to appear. It seems that the #invoke: magic in mw:Extension:Scribunto only evaluates each parameter when first needed, so |text_IPS={{fb...{{efn...}} }} only produces a footnote if someone looks at the value of args.text_IPS. Footnote f in Wikipedia:Guide to Scribbling provides minimal evidence for this theory. Certes (talk) 18:01, 3 November 2019 (UTC)
... whereas Module:Arguments uses metatables to fetch arguments from #invoke ... without using the pairs() function. Certes (talk) 18:08, 3 November 2019 (UTC)
I haven't had a chance to look at this but that analysis looks correct to me. Module:Navbox reads its arguments before doing anything with the reason in a comment: "Read the arguments in the order they'll be output in, to make references number in the right order". Johnuniq (talk) 01:05, 4 November 2019 (UTC)
Yes, this is correct. If you only use syntax like args.foo or args["foo"] with an argument table output from Module:Arguments, then pairs() isn't called on the original #invoke arguments. However, if you call pairs() on the argument table, each argument from #invoke is fetched using the next() function, which has the same effect as using pairs() on the original #invoke arguments. — Mr. Stradivarius ♪ talk ♪ 01:40, 4 November 2019 (UTC)
This may be obvious but I think it's worth repeating: |text_IPS={{fb...{{efn...}} }} evaluates as as part of the template expansion process; the module only sees the expansion of {{fb|...}}. That expansion has the side effect of creating a footnote but occurs only when Lua needs to determine the value of args.text_IPS during lazy evaluation. I'm not a veteran Lua coder, so please correct me if any of that is wrong! Certes (talk) 11:30, 4 November 2019 (UTC)
interesting. since it looks like Module:Arguments can iterate over the args without creating these ghost references, I tried this to filter out the offending entry, but even that doesn't work. is there any way to remove this arg from the table without creating a ghost reference? Frietjes (talk) 14:40, 4 November 2019 (UTC)
I've done quite a few experiments and I don't think Module:Arguments really iterates over the args at all. What it seems to do is set up a table with a function to access its values. Calling that function has the same side effect of evaluating the footnote as any other type of access to the table value. The apparent magic is that getArgs does not actually call the function but merely associates it with the table so that any attempt to read the value later still triggers the footnote. What we need is a way to get a list of keys of a table without reading their values, so that we can iterate over it with something like if key == "text_IPS" then return nil else return table[key] end. Disappointingly, I can find no way to get a list of keys without evaluating their values, even with heavy metatable manipulation. Certes (talk) 18:48, 4 November 2019 (UTC)
I'm pretty sure it cannot be done. If there were a strong need, we might ask for a Scribunto enhancement so a module could call a function to get a table of parameter names. Scribunto might be able to do that without evaluating each parameter, but I don't know. Johnuniq (talk) 22:39, 4 November 2019 (UTC)

Is there a way to get the name of a variable in Lua?

Is there a way to get the name of a variable in Lua? My use-case, I have a list of parameters passed via a template to a module and they differ by a suffix letter. I need to sum the values of all variables that end with the same letter together.

So for this local args = {arg1W = 2, arg1L = 3, arg2W = 3, arg2L = 5}, is it possible to get the string value of the parameter names (know that args1W is "args1W")? --Gonnym (talk) 13:55, 20 November 2019 (UTC)

All args from the template are available in the args member of the parent frame so you can:
local parent_args=mw.getCurrentFrame():getParent().args
for param_name, param_val in pairs (parent_args) do ... end
caveat lector: the above not tested
Trappist the monk (talk) 14:08, 20 November 2019 (UTC)
Just to expand a little, you can set an array to hold the sums, indexed by suffix letter, and then use that later.
local sums = {}
for param_name, param_val in pairs (parent_args) do
	local letter = param_name:sub(-1)
	sums[letter] = (sums[letter] or 0) + param_val
end

for k, v in pairs(sums) do
	-- do something: k is the letter, v is the sum for that letter
end

-- or just use sums.W and sums.L if you know what sufix letters are going to be passed
Tested at https://www.lua.org/cgi-bin/demo but not in a module. HTH --RexxS (talk) 17:23, 20 November 2019 (UTC)
Thanks both! --Gonnym (talk) 17:39, 20 November 2019 (UTC)
Module:Timeline of release years has a few flavors of an implementation for the application need described. --Izno (talk) 20:17, 20 November 2019 (UTC)

Requested move 8 November 2019

The following is a closed discussion of a requested move. Please do not modify it. Subsequent comments should be made in a new section on the talk page. Editors desiring to contest the closing decision should consider a move review after discussing it on the closer's talk page. No further edits should be made to this discussion.

The result of the move request was: No consensus to move the listed talk pages. While some of the participants agreed there was no harm in moving the talk pages, most felt that it made more sense to discuss changes to a module on the module's talk page. In total there were no strong opinions in either direction, so the status quo will be maintained. Primefac (talk) 13:25, 23 November 2019 (UTC)



– Modules that are used solely to implement one template are internal stuff; the actual non-programmer-facing page is the template, so any discussion about the template should happen on the template talk page, not the module talk page. * Pppery * it has begun... 22:10, 8 November 2019 (UTC) Relisting. Primefac (talk) 13:14, 16 November 2019 (UTC)

@Pppery: Hi. I am the developer of War Map Templates/Modules, which include 8 of the items you list above. I just want to make sure nothing will get messed up. Is this really necessary? The reason we have done it this way thus far (discussion in module talk with template talk redirecting to module talk) is because the updating of the maps take place in the module. So people are editing the module and discussing the changes at module talk. The template is basically fixed from the beginning and does not get edited. So basically all the action is in the modules. People have been used to this for years and i am afraid they will get lost if we change it. Also, i wonder if some links will get messed up... Tradediatalk 08:42, 16 November 2019 (UTC)
Of course, it's desirable that discussion about one topic should happen one a single talk page, but it doesn't seem to me that it has to automatically be the template talk page. A single module can, of course, contain multiple related calls that could be invoked by several individual wrapper templates; in those cases, we would want discussion at the module talk page (Module:String2 is an example). Similarly there are complex templates that invoke several different modules, and clearly discussion of that template has to be on the template talk page (e.g. Template:Wikidata infobox). I don't think we should be trying to make hard-and-fast rules about where the discussion takes place.
Nevertheless, in cases such as these, where the template is a wrapper to a module, and there is 1:1 correspondence, it surely doesn't matter which talk page is actually used because a redirect from the other talk page will lead users to the discussion in any case. If multiple editors are working on the module (and that's a very good sign, in my humble opinion!), my inclination would be to leave things alone, but I don't feel strongly about it. --RexxS (talk) 13:44, 16 November 2019 (UTC)
@Tradedia: This will move the talk pages from module talk to template talk namespace, leaving a redirect. I don't see how that could mess anything up. * Pppery * it has begun... 19:28, 16 November 2019 (UTC)
Yeah I hear you @Pppery:… it’s just that I’m risk averse and a proponent of “if it ain’t broken, don’t fix it”… Tradediatalk 06:13, 17 November 2019 (UTC)
for the described workflow (ppl participate in talk page discussion, then editing module), move seems unnecessary, and makes life a tad more tedious: it's convenient to see at the top of the page "Module" and "Talk" tabs, and the ability to switch between them.
for cases where a module serves a single template, and practically all the discussions on talk page involves ppl who are not editing the module or read its code, this move seems harmless, although i am still not sure it carries real value, either. peace - קיפודנחש (aka kipod) (talk) 20:57, 18 November 2019 (UTC)

The above discussion is preserved as an archive of a requested move. Please do not modify it. Subsequent comments should be made in a new section on this talk page or in a move review. No further edits should be made to this section.

If one of you Lua programmers could parametrize this for me, I'd very much appreciate it.   The current hatnote seems rather derp when used in the context I've described and I'd rather not use custom hatnotes unless I have no other choice. Seppi333 (Insert ) 17:05, 30 November 2019 (UTC)

Never mind. There's an obvious alternative that I missed. Seppi333 (Insert ) 19:47, 30 November 2019 (UTC)

Looped args with TemplateData template

I'm trying to make a template that helps with TemplateData (basically, makes it a bit less complicated to do and has it in template form. User:Lemondoge/templatedata) Currently it only supports 3 parameters, and I am trying to figure out how to make it support infinitely many parameters. I have an unfinished module page for it (Module:Sandbox/Lemondoge/templatedata), but I can't figure out how to make it work - already stuck on how to concatenate arguments to create JSON format. Any help? (See template page and documentation for information on the usage of the template in its current state.) {​{Lemondoge|Talk|Contributions}} 19:45, 2 December 2019 (UTC)

First, in the template, enumerate parameters with digits not with text; if you don't, parameter names will get really ugly really fast. Do not mix positional parameters with named parameters; that will simply cause you headaches and confusion down the road so: |label1=, |param1=, |description1=, |type1=, |status1=; then |label2=, ... etc.
You can create a loop that calls a function by doing something like:
require('Module:No globals');
local getArgs = require ('Module:Arguments').getArgs;

local function function_that_does_stuff (label, param, description, ptype, status)
	local result
	-- wherein stuff gets done that sets result
	return result
end

local function templatedata (frame)
	local args=getArgs (frame)
	local final_result
	
	local i=1

	while frame.args['label'..i] do
		local result = function_that_does_stuff (args['label'..i], args['param'..i], args['description'..i], args['type'..i], args['status'..i])
		-- here do something with result to fill final_result
		i = i + 1;
		
	end
	
	-- here do something to finish off final_result
	
	return final_result
end

return templatedata
caveat lector: the above is just hacked from the top of my head; not tested, probably has bugs, but should serve as a starting place.
Trappist the monk (talk) 20:19, 2 December 2019 (UTC)
As far as what I'm doing goes, this does not seem to function properly. If I leave this unmodified for debug and just invoke the function, it gives this: "Script error: The module returned a function value. It is supposed to return an export table." Otherwise, final_result seems to just not be written to at all - unless I just define it as a string (e.g. local final_result = "poof"), the template will do nothing, regardless of parameters. Current code is:
require('Module:No globals');
local getArgs = require ('Module:Arguments').getArgs;
local p = {}
local function function_that_does_stuff (label, param, description, ptype, status)
	local result
	result = '"'..param..'": { "label": '..label..'", "description": "'..description..'", "type": "'..ptype..'", "required": '..status..' },'
	return result.."poof"
end

function p.templatedata (frame)
	local args=getArgs (frame)
	local final_result
	local i=1

	while frame.args['label'..i] do
		local result = function_that_does_stuff (args['label'..i], args['param'..i], args['description'..i], args['type'..i], args['status'..i])
		final_result = final_result..result
		i = i + 1;
		
	end
	
	return final_result
end

return p
{​{Lemondoge|Talk|Contributions}} 22:54, 2 December 2019 (UTC)
Update: hold up it gives you a sort of VisualEditor thingamajig for doing TemplateData on the top-left of a template documentation page when you're editing it - apparently this template thing is basically just pre-deprecated and useless. abort mission {​{Lemondoge|Talk|Contributions}} 23:10, 2 December 2019 (UTC)

Again looped args

Hi, I just continue with Lemondoges request - which does not bear an answer to my problem:

  1. a template gets an unknown, possibly large amount of parameters. For each parameter the same action is required (it does not matter whether there are single parameters, pairs or other tupels, and when there are named global parameters in addition).
  2. The parameters are passed to a Lua module, which analizes them, and performs a loop through the parameter list.
  3. For each action the parameter (or parameters) must be passed to kind of layout template which performs the action, whatever it may be.

But at the moment I am not able to perform a repetitive frame:expandTemplate{ title = title, args = } where the argument[s] are one after the other the values from a loop; Lua seems to allow only one frame:expandTemplate{} as the only one return value? When that is the concept of Lua, this restriction should be expanded, because there are numerous templates having problems with long parameter lists! Poor code constructions like {{#if:{{{1|}}}|... until e.g. {{#if:{{{33|}}}|... will fail as soon as there are 34 parameters to handle. A loop in Lua can serve any uncountable number of parameters, when the repetitive transclusion is possible. sarang사랑 16:40, 14 January 2020 (UTC)

If your parameters are all positional {{{1}}} ... {{{n}}} then you might write something like this (untested and presuming that you have extracted an args table from the appropriate frame):
local out = {}
for i, v in ipairs (args) do
  table.insert (out, frame:expandTemplate{ title = title, args = v })
end
return table.concat (out)
Each time through the loop you get the next enumerated parameter value, call the template on that value, insert the result in the output table. When done looping, concatenate all of the template outputs into a big-damn-string and return that big-damn-string.
A sandbox showing what you have done so far, almost never goes amiss when asking for help.
Trappist the monk (talk) 16:56, 14 January 2020 (UTC)
@Trappist the monk: thank you very much, your solution works! I never got that idea, but now I am happy that I can solve lots of problems. sarang사랑 12:26, 16 January 2020 (UTC)

System variables

Another thing I cannot find information about: sure there must be an access to the system variables (of course it can be passed by a template, but how con I get it directly by the Lua code); how can I get e.g. environment parameters like the {{PAGENAME}} where the code is executed? sarang사랑 12:25, 19 January 2020 (UTC)

Does mw.title.getCurrentTitle().text do what you want? If you are looking for the name of the module then frame:getTitle(). Have you looked in mw:Extension:Scribunto/Lua reference manual?
Trappist the monk (talk) 13:14, 19 January 2020 (UTC)
Yes, it is; thank you. I checked through the reference but I could not understand that that is what I needed. sarang사랑 06:29, 21 January 2020 (UTC)

Improvement to Module:Trim quotes to distinguish single/double quoting from bold and italics wikimarkup

Please see Template talk:Trim quotes#Wikimarkup interference. Trying to get Lua to do this gives me a headache, though I could do it easily in bash or Perl or whatnot. Lua just hasn't sunk in yet.  — SMcCandlish ¢ 😼  21:35, 30 January 2020 (UTC)

Module:Is_stub

I just created Module:Is_stub for merging {{uncategorized stub}}. It detects if a page is tagged with a stub tag or not with a very high accuracy. Could someone please tell me either point me to the existing template for this purpose or tell me why this is a bad idea. I won't believe that this is the first time someone have thought of this. ‑‑Trialpears (talk) 21:54, 30 January 2020 (UTC)

Redundant to Module:Page and Module:String. {{#if:{{#invoke:String|match|{{#invoke:Page|getContent|{{FULLPAGENAME}}|as=raw}}|stub|ignore_errors=1}}|yes|no}} does the exact same thing without creating more module bloat. * Pppery * it has begun... 00:17, 31 January 2020 (UTC)
Thanks, I turned it into {{Stub other}}. ‑‑Trialpears (talk) 09:48, 4 February 2020 (UTC)

Discussion at Wikipedia:Templates for discussion/Log/2020 February 13#Module:HelloWorld

  You are invited to join the discussion at Wikipedia:Templates for discussion/Log/2020 February 13#Module:HelloWorld. * Pppery * it has begun... 22:28, 13 February 2020 (UTC)

  You are invited to join the discussion at Wikipedia:Help_desk#Why_do_so_many_commonly-used_templates_use_MODULES?_When_they_don't_need_to?. * Pppery * it has begun... 01:15, 15 February 2020 (UTC)

Connecting Wikipedia articles to reliable sources through new template

Hi All,

Please have a look at my proposal and contribute with your opinions: Wikipedia:Village_pump_(proposals)#Connecting_Wikipedia_articles_to_reliable_sources_through_new_template

Thanks, Adam Harangozó (talk) 14:14, 23 February 2020 (UTC)

Get all pages in a category

Hi! Is there a way to get the list of pages in a category within a Lua module? I checked the Lua reference manual carefully, thought about it and tried a few things, but no luck, so before giving up I thought about asking here. Thanks! Sophivorus (talk) 19:15, 23 March 2020 (UTC)

We've discussed this a few times and believe it to be impossible. You can display the list of members on a page in a way visible to the reader, but there is no way for Lua to read its contents back. Certes (talk) 19:33, 23 March 2020 (UTC)
It would be possible if mw:Extension:CategoryToolbox would be enabled on this wiki. --Gonnym (talk) 11:08, 24 March 2020 (UTC)
Actually looking at it now, the doc doesn't show it has an option to get all pages in category, but to check if a page is in a category, so nevermind. --Gonnym (talk) 11:10, 24 March 2020 (UTC)
The real fix for this and other similar problems is allow lua to fetch the content of strip markers. It used to be, for example, that it was possible to get the content of <math>...</math> tags from the math strip marker using mw.text.unstripNoWiki(). That was, and still is important to me because the content of <math>...</math> tags is rendered as images. cs1|2 creates metadata for use by Zotero and other reference management software. But, the metadata doesn't accept the transient images that mediawiki uses to render the equation. For the metadata, cs1|2 used to get the content of the math strip marker and extracted the original source equation from the <math>...</math> tags for use in the metadata. But, mediawiki took away that ability so now, metadata for article titles with equations use MATH RENDER ERROR text in place of the equation (better that than as percent encoded version of the strip marker).
Trappist the monk (talk) 12:21, 24 March 2020 (UTC)

Script to fetch the nutshell text of a given page

Per this discussion at the VPT (start reading at "related idea"), we'd like to have a module that can take as input a given page and return the text from the {{Nutshell}} on that page if one exists (and return "null" or something if the page doesn't have a nutshell). Would that be possible to create without too much effort? {{u|Sdkb}}talk 21:14, 4 April 2020 (UTC)

Scripts and lua are not the same thing. At least I don't see them as the same thing. A script runs on your browser. Lua runs when MediaWiki compiles wikitext into the html that your browser displays as an article. If you are looking for a script, then this place is not the right place to be looking.
If you are looking to create shortcut templates that have tooltips where the text of the tooltip is taken from a {{nutshell}} template in the target page, I think that can be done. But shortcuts often link to sections that don't have {{nutshell}} and for for those that do the search has to be constrained to that section and you have to look for {{nutshell}} and all of its redirects:
{{Essay in a nutshell}}
{{Guideline in a nutshell}}
{{Guideline one liner}}
{{In a nutshell}}
{{Inanutshell}}
{{Naming convention in a nutshell}}
{{Nutshell2}}
{{Policy in a nutshell}}
{{Policy proposal in a nutshell}}
{{Proposal in a nutshell}}
Trappist the monk (talk) 21:41, 4 April 2020 (UTC)
See Template:Template parameter value * Pppery * it has begun... 21:43, 4 April 2020 (UTC)
Something else to consider, wiki markup in a nutshell template. For example, this is the parameter value at WP:EP
Improve pages wherever you can, and do not worry about leaving them imperfect. Preserve the value that others add, even if they "did it wrong" (try to fix it rather than [[WP:Deletion policy|delete it]]).
Converting that to a titletip:
[[WP:EP|<span title="Improve pages wherever you can, and do not worry about leaving them imperfect. Preserve the value that others add, even if they 'did it wrong' (try to fix it rather than [[WP:Deletion policy|delete it]]).">WP:EP</span>]]
WP:EP
For the purposes of example, I manually changed the double quotes within the nutshell text to single quotes within the span; those kinds of things will also need to be handled.
Trappist the monk (talk) 22:59, 4 April 2020 (UTC)
@Sdkb and Trappist the monk: I've started this module. See Module:Nutshell, and User:Guywan/Test2, where it is used. Needs some work yet, I'm no Lua expert. guywan (talkcontribs) 14:49, 5 April 2020 (UTC)
We always seem to forget that whitespace around template names is allowed. Here is a table of {{nutshell}} redirect patterns with whitespace; works well with ipairs():
local redirects_nutshell_patterns = {
	'{{%s*[Nn]utshell%s*|',
	'{{%s*[Ee]ssay in a nutshell%s*|',
	'{{%s*[Gg]uideline in a nutshell%s*|',
	'{{%s*[Gg]uideline one liner%s*|',
	'{{%s*[Ii]n a nutshell%s*|',
	'{{%s*[Ii]nanutshell%s*|',
	'{{%s*[Nn]aming convention in a nutshell%s*|',
	'{{%s*[Nn]utshell2%s*|',
	'{{%s*[Pp]olicy in a nutshell%s*|',
	'{{%s*[Pp]olicy proposal in a nutshell%s*|',
	'{{%s*[Pp]roposal in a nutshell%s*|',
	}
I recently wrote a function to strip all wikilinks from a template. You might find this useful because who knows how many wikilinks will appear in nutshell text:
local function wikilink_strip (template)
	for wikilink in template:gmatch ('%[%b[]%]') do								-- get a wikilink
		if wikilink then
			template = template:gsub ('%[%b[]%]', '__57r1P__', 1);				-- install a marker
			if wikilink:match ('%[%[.-|(.-)%]%]') then
				wikilink = wikilink:match ('%[%[.-|(.-)%]%]');					-- extract label from complex [[link|label]] wikilink
			else
				wikilink = wikilink:match ('%[%[(.-)%]%]');						-- extract link from simple [[link]] wikilinks
			end
			wikilink = escape_lua_magic_chars (wikilink);						-- in case there are lua magic characters in wikilink
			template = template:gsub ('__57r1P__', wikilink, 1);				-- replace the marker with the appropriate text
		end
	end

	return template;
end
The if wikilink then may not be necessary. I think it is a left-over artifact from an earlier version of the code that did not work.
The above doesn't answer the what to do about templates found in a nutshell template (preprocess them, I suppose). What to do about html? I don't think that bullet points are supported in tooltips so string them all together? What about prefixing? Use the default title text or the default title text modified by |title=? Ignore?
Consider using find() to find a particular nutshell pattern then, with the start position returned from find(), use match ('%b{}', start) to get the whole template.
Is it really necessary to use the ustring functions?
Find a better module name. Module:Nutshell implies that it is used to implement all or part of {{nutshell}}; it is not.
Trappist the monk (talk) 15:42, 5 April 2020 (UTC)
@Trappist the monk: Thanks for your suggestions. I'd say strip anything that isn't sentence-like.
Find a better module name. I'm not passionate about the name. You are welcome to give it another one.
Is it really necessary to use the ustring functions? Not anymore :)
escape_lua_magic_chars() Where is this defined, and how important is it?
Regards, guywan (talkcontribs) 22:19, 5 April 2020 (UTC)
Here:
--[[--------------------------< E S C A P E _ L U A _ M A G I C _ C H A R S >----------------------------------

Returns a string where all of lua's magic characters have been escaped.  This is important because functions like
string.gsub() treat their pattern and replace strings as patterns, not literal strings.

]]

local function escape_lua_magic_chars (argument)
	argument = argument:gsub("%%", "%%%%");										-- replace % with %%
	argument = argument:gsub("([%^%$%(%)%.%[%]%*%+%-%?])", "%%%1");				-- replace all other lua magic pattern characters
	return argument;
end
If I can remember, I think that I added this to wikilink_strip() because something that was being stripped had a percent-encoded space (%20) in it that caused lua to choke because it saw that as a capture reference that it had not captured. You may never encounter that problem. I don't remember why I separated the % escape from the rest of the lua magic characters. I've had no reason to change it because it has been working since I don't remember when.
What do you intend to call User:Guywan/Test2 when it becomes a template? Use that name for this module?
Trappist the monk (talk) 23:07, 5 April 2020 (UTC)
@Guywan and Trappist the monk: Glad to see progress being made here! I would prefer for the template to be able to be called using {{WP|BOLD}}. But maybe the WP should just be a shortcut and the template itself should be given a better name. Pppery, I'm having some trouble getting {{Template parameter value}} to work correctly. Do you or anyone else know what I'm doing wrong at User:Guywan/Test2? {{u|Sdkb}}talk 22:26, 7 April 2020 (UTC)
Template:Template parameter value is a bit finnicky. First, you have to pass the redirect target to it, rather than the redirect itself. Secondly, it cares about the capitalization of {{nutshell}} on the target page. For instance,
{{template parameter value|{{#invoke:Redirect|main|WP:BOLD}}|nutshell|1|1|1|1}}
Go for it. works, but
{{template parameter value|{{#invoke:Redirect|main|WP:BOLD}}|Nutshell|1|1|1|1}}
Go for it. does not. Alex 21 (the author of {{template parameter value}}), what do you think about updating the template to automatically bypass redirects and ignore the case of the first character in the template name? * Pppery * it has begun... 22:41, 7 April 2020 (UTC)
@Guywan, Trappist the monk, Pppery, and Alex 21: Okay, so checking in on where we're at, it looks like we're pretty close, since User:Guywan/Test2 currently works based on Module:Nutshell. The only issue is that, when used for pages without a nutshell, it returns a big error message, rather than just returning a link to the page without a tooltip or dotted underline, as would be preferable. Is there any easy way to get that behavior? Once that's done, I think we'll be ready to move out of userspace and into template space and start using. {{u|Sdkb}}talk 02:59, 11 April 2020 (UTC)
I hacked on Module:Nutshell for a bit. I moved the tooltip creation into the module reorganized how the nutshell template is disassembled, added support for multiple positional parameters, and support for extracting a value from |title=.
There is this one:
{{#invoke:WP | main | SIG }}WP:SIG
In the positional parameter it has [[File:OOjs UI icon signature-ltr.svg|22px]] ( ) renders in the tooltip as 22px; what to do about that?
Trappist the monk (talk) 19:22, 11 April 2020 (UTC)
Code tweaked to replace the image with text: [IMAGE]. I suppose that we could parse apart the image wikilink for alt text or caption. Is it worth it? We might get some text to go in the tooltip but that text might not fit grammatically in the rest of the tooltip.
Trappist the monk (talk) 19:37, 11 April 2020 (UTC)
@Trappist the monk and Guywan: I've gone ahead and launched the template at Template:WP, since it seems to be working pretty well. For a further improvement (and looking at the code, this may already be in progress), it'd be good to have the page title written out in the tooltip instead of "this page", so that the tooltip for WP:BLP reads Biographies of living persons in a nutshell: Material about... instead of This page in a nutshell: Material about... Once you've made all the improvements you want, lmk and we can announce it at the Community bulletin board. {{u|Sdkb}}talk 07:32, 12 April 2020 (UTC)
Here are some questions that I think need answers:
  • when the nutshell holds an image, is it worth the effort to parse apart the File: or Image: wikilink to extract alt text or caption text?
  • there is code in Module:WP that looks for a stub template and if found, causes an error return. Why do we care if the target page is a stub?
  • should this module accept MOS:... or other namespace abbreviations? WP:LIST is a shortcut to a dab page that includes the MOS:LIST target which has a {{nutshell}} template.
Trappist the monk (talk) 17:25, 12 April 2020 (UTC)

@Trappist the monk: Re image, it seems very rare for an image to be in a nutshell, so I'd say no. The alt text might occasionally work, but it's just as (if not more) likely to be missing or incomplete, which would just add to the confusion. The current solution of "[IMAGE]" at least alerts the reader that there's an image there and that they might just want to click through.

Re stubs, it seems perfectly possible that a stub would have a nutshell, so I don't see why we'd want to exclude them from the template. Maybe figure out the WP:FENCE aspect, but if there's nothing technical making it necessary, just get rid of it.

Re other namespace abbreviations, Template:MOS, unlike Template:WP, is taken, so it'd be hard to allow {{MOS|LEAD}}, but WP:LEAD works fine, and goes to the same place.

And I'm glad to see the page titles now being included! (Thanks for coding that!) I notice that it can get a bit confusing for some, as in WP:BITE seems to be talking about biting newcomers in a nutshell (lol) with the current Wikipedia:Please do not bite the newcomers in a nutshell: Do not be... Adding quotes around the title could fix that. We could also use a period or line break to make it clearer that the link goes to the page. Together with those changes, we'd have something like "Wikipedia:Please do not bite the newcomers". In a nutshell: Do not be... I'm also on the fence about whether to we should take out the "Wikipedia:" — do you think it adds enough to be worth including?

Oh, and one thing showing up in WP:NPOV and a few other test cases is that italics and bolding aren't being reflected. Do Wikipedia tooltips have the technical capability to handle formatting like that? (If so, it might be nice to bold the article title to help it stand out a bit.) {{u|Sdkb}}talk 19:45, 12 April 2020 (UTC)

I concur that image alt text or caption text would be problematic in that, when it exists, and the likely hood of that happening is rather remote, whatever text is in the image markup won't fit grammatically with the surrounding text.
This search finds no stubs that use {{nutshell}}. Just to prove that the stub search portion of that isn't broken, this search finds about 2500 stub templates. Given these results, I'm going to delete that snippet of code. If it turns out that there is a reason for it being there, the code is in the history of the module so it can be dredged up and restored.
I was thinking more along the lines of accepting a MOS: prefixed argument ({{WP|MOS:LEAD}}) that would render as MOS:LEAD (with the tool tip and dotted underlining). It is my understanding that MOS shortcuts are preferred for the manual of style. Maybe I'll hack something into this code to see how that would work.
I've added quotes around the article title. I have not added the full stop. You did, showing it outside the quotes. That is one of the grammatical things I almost always get wrong so I don't know if the dot goes inside or outside. So I've left it off until someone confirms your usage. I've been thinking that the 'Wikipedia:' prefix should be shortened to 'WP:' in keeping with the template name: "WP:Please do not bite the newcomers" in a nutshell: Do not be....
Italic and bold markup will not work. To prove that, I did an experiment. I added <b>...</b> around the article title portion of the tooltip. Not surprisingly, html tags inside a title attribute inside a <span> confused MediaWiki so the enclosing <span>...</span> rendered as linked plain text (but the title was bold). Right now, we do nothing with the bold and italic markup so where it exists in the {{nutshell}} text, it shows up as raw markup in the tooltip. Leave it because we all know what it means, or strip it?
Trappist the monk (talk) 22:43, 12 April 2020 (UTC)
My experience elsewhere is that image handling can make a simple module very complex. Images hidden in infoboxes with unusual parameter names, non-free images with rationales for the source but not the destination, complex wikitext within captions and other gotchas can take more coding and CPU time than the module's actual purpose. Avoid if possible. Certes (talk) 22:55, 12 April 2020 (UTC)
Stub code gone.
MOS: prefixed shortcuts:
{{WP|MOS:LEAD}}MOS:LEAD same as {{WP|WP:LEAD}}WP:LEAD and {{WP|LEAD}}WP:LEAD
{{WP|MOS:TM}}MOS:TM not the same as {{WP|WP:TM}}WP:TM and {{WP|TM}}WP:TM
{{WP|MOS:MED}}MOS:MED not the same as {{WP|WP:MED}}WP:MED ?? {{WP|MED}}WP:MED
This facility might also be expanded to the Help namespace.
Trappist the monk (talk) 00:20, 13 April 2020 (UTC)
@Trappist the monk: Regarding the full stop, it saddens me to report this, since I'm very much #TeamInside, but per the MOS, Wikipedia style is to have it outside. And I agree that WP would be good — it's shorter than writing out Wikipedia while making it clearer that the thing in quotes is a page title than leaving it out. {{u|Sdkb}}talk 00:39, 13 April 2020 (UTC)
Support added for Help namespace and Wikipedia namespace alias Project:
{{WP|Help:CS1}}Help:CS1
{{WP|Project:LEAD}}Project:LEAD
Namespaces and namespace aliases are case insensitive but pseudo namespaces are treated like article names so only the first character is case insensitive. The supported pseudo namespaces are H and MOS:
{{WP|h:CS1}}Help:CS1
{{WP|mOS:MED}}MOS:MED
but
{{WP|mos:MED}}MOS:MED
Trappist the monk (talk) 15:01, 13 April 2020 (UTC)
@Trappist the monk: I've made some minor changes, mostly to the main function. I unified namespaces and pseudo_namespaces so we only have to lookup in one table. Namespace input like h, H, pRoJeCt, and mOs are 'normalised' to Help, Project, and MOS. guywan (talkcontribs) 14:27, 14 April 2020 (UTC)
I notice that, with the page previews setting turned on, uses of this template with MOS seem to be displaying a preview, but not others. Can we resolve that discrepancy? {{u|Sdkb}}talk 21:51, 14 April 2020 (UTC)
Not the fault of this module. With page previews enabled, compare:
{{WP | MOS:MED }}MOS:MED
[[MOS:MED]]MOS:MED
MOS is a pseudo namespace that actually lives in mainspace. This is why:
[[mOS:MED]]mOS:MED works
[[mos:MED]]mos:MED does not work
MOS:... shortcuts are merely mainspace redirects that look like <namespace>:<title> shortcuts into another namespace. Namespace names and aliases are case insensitive and separated from the shortcut's article title with the colon. The title portion must obey the same case-sensitivity rules as any other page title:
[[wp:MED]]wp:BOLD works; nominal redirect (page ID: 1502969)
[[wp:mED]]wp:bOLD works; same redirect as above (page ID: 1502969) because of the first-character case-insensitivity rule
[[wp:med]]wp:bold works; another redirect from WP:Bold (page ID: 1502965)
[[wp:mEd]]wp:bOLd does not work; no redirect
"So that, as clear as is the summer's sun" (Shakespeare Henry V act 1, scene 2) is why there appears to be an issue, and there may be, but it is nothing that you can do anything about except discontinue support for MOS shortcuts.
Trappist the monk (talk) 00:47, 15 April 2020 (UTC)

can we look up "globalSiteId' of the wiki the code is running on?

Does anyone know how to look up "globalSiteId' of the wiki the code is running on? So "enwiki" on English wikipedia, "commonswiki" for Commons, etc. I am updating c:Module:Interwiki and would like to ensure that the module will not add link to itself, even if copied to other wiki. --Jarekt (talk) 19:39, 22 April 2020 (UTC)

@Jarekt: {{#invoke:WikidataIB |globalSiteID}} → enwiki
The Lua call is mw.wikibase.getGlobalSiteId(). Cheers --RexxS (talk) 19:58, 22 April 2020 (UTC)
Thanks --Jarekt (talk) 01:26, 23 April 2020 (UTC)

Non-Mediawiki?

Do really http://lua-users.org/wiki/ a resource included the Lua list here, does not use MediaWiki? :-? BoldLuis (talk) 09:15, 18 May 2020 (UTC)

It uses UseModWiki, which achieves similar results using different syntax.[1] Certes (talk) 11:28, 18 May 2020 (UTC)

Retrieving the display title value

Is there a way in Lua, magic words or regular template syntax to get the Display title value of a page (which doesn't involve reading the page content)? Wondering since its a value shown in the Page information of a page. --Gonnym (talk) 07:56, 20 May 2020 (UTC)

See phab:T154738 * Pppery * it has begun... 13:18, 20 May 2020 (UTC)
@Gonnym: Is this sufficiently different from {{FULLPAGENAME}} to cause problems for your application?
One workaround might be to use the fact that almost all articles (and some other pages) have an associated Wikidata entry that has a sitelink back to the article using its display title. So for iCarly, season 6 (Q10044351), you can use {{#invoke: WikidataIB |getSiteLink |qid=Q10044351}} to get 'ICarly season 6'. Leaving out the |qid= will use the connected article for the page: {{#invoke: WikidataIB |getSiteLink}} → .
Obviously it won't work on pages that don't have a connected Wikidata item. --RexxS (talk) 16:43, 20 May 2020 (UTC)
If the Display title is the desired result then the wikidata won't work because the displayed title is: iCarly (season 6) – italics and first character lowercase. Even if it were possible to get the displayed title, how would it be returned?
as wiki markup? ''iCarly'' (season 6)
as html? <i>iCarly</i> (season 6)
Trappist the monk (talk) 16:54, 20 May 2020 (UTC)
RexxS, I think maybe Wikidata might be overkill for this. The problem isn't that big, so was hoping that there might have been a simple solution. Thanks for the help guys. --Gonnym (talk) 17:11, 20 May 2020 (UTC)
  • Rough Lua code to parse the page content (definitely needs care (not that expensive (about 1.0 out of 50 MB)):
    • {{#invoke:Sandbox/Matroc/Misc|getdisplay|page=ICarly (season 6)}} (can be used with (safesubst) and getdisplay function can be modified as to error checking and whats to be output.
    • iCarly (season 6) -- result is iCarly (season 6) -- Matroc (talk) 06:54, 31 May 2020 (UTC)
You may be able to adapt Module:Template parameter value, which relies on the value being introduced by a pipe rather than a colon. However, many articles have their displaytitle modified by a template such as {{lowercase title}}, or indirectly via an infobox template per WP:ITALICTITLE. Certes (talk) 08:36, 31 May 2020 (UTC)
Thank you for further clarification - my example was a simple solution and does not cover the variety of ways a DISPLAYTILE can appear -- Matroc (talk) 01:56, 1 June 2020 (UTC)

Radio buttons for switching between historical maps

 
 
El'ad
El'ad (Central Israel)
 
 
El'ad
El'ad (Israel)
 
El'ad 2020 street map overlaid on Survey of Palestine map from 1941

Please could someone help to create radio button functionality for switching between historical maps?

Currently Module:Location map gives the ability for a reader to switch between contemporary map views using radio buttons (see example on the right). For historical maps, comparing what an area looks like today to how it looked historically, there is no template or module which can do the same. It would benefit articles about historical settlements which look very different today (for example Tenochtitlan in Mexico City, Cahokia in St. Clair County, Illinois, Londinium in London and Lutetia in Paris). The best I have been able to come up with is the gif on the right, but it has been fairly derided as overly "distracting".

Would it be possible to extract the relevant code from Module:Location map into a new "Module:Image select" or similar? It doesn't need any of the other functionality (e.g. coordinates, labels) as it can all be covered by the buttons and captions.

Onceinawhile (talk) 09:21, 24 June 2020 (UTC)

You're looking for {{switcher}} * Pppery * it has begun... 13:56, 24 June 2020 (UTC)
@Pppery: that is perfect, thank you. Onceinawhile (talk) 14:19, 24 June 2020 (UTC)

Help find and remove a testing module

Right now Module:SimpleDebug is transcluded into Cynthia Brewer. My assertion is that we should avoid transcluding testing modules. Can someone see if they can remove that use from there? --Izno (talk) 15:01, 20 July 2020 (UTC)

Commented out the require in Module:TNTTools because it did not appear to be used in that module.
Trappist the monk (talk) 15:18, 20 July 2020 (UTC)
It comes from {{BrewerColors}} which I believe is a recreation of {{BrewerPalette}} (TfD). I think merging it with the article and then G4 would be a proper course of action. Alternativley it could be removed as too much detail instead relying on the external link to ColorBrewer2.org. --Trialpears (talk) 15:20, 20 July 2020 (UTC)
No, it is not a recreation. TFD is probably reasonable. --Izno (talk) 15:38, 20 July 2020 (UTC)
As the nominator of the aforementioned TfD, I can say clearly that {{BrewerColors}} is not a recreation of {{BrewerPalette}} (the latter template used the former). Nor do I see why {{BrewerColors}} should be deleted. @Izno and Trialpears: What's the problem with {{BrewerColors}} exactly? * Pppery * it has begun... 16:08, 20 July 2020 (UTC)

Module:Sports rbr table + Template:F1R2020

Throughout the motorsport we use mostly similar color schemes and tables. And in the popular motorsport we use and update the same data but we update it on the different pages doing more edits than we actually need. I made an intermediate solution but it is a bit clumsy. All motorsport community will be pleased if you help us to made a module for the motorsport tables (their common look here. P.S. Also we had two slightly different tables , but probably they also could have connection and receive updates from the same source template/module. The example of the cells from such tables below: {{F1R2020|HAM|HUN}}

1PF
HUN
1

P.S.S. The issue with Module:Sports rbr table is that we can't add Template:F1 race position or bold/italics. Also we need a possibility to add extra column for positions and numbers (in the case of the teams' standings). Corvus tristis (talk) 03:39, 26 July 2020 (UTC)

Election results module

Hello. Is anyone able to help me sort out Module:Election results/sandbox? I can't work out what I've done wrong to make {{Election results/testcases}} go wrong for the latter two tables. I suspect it's something to do with the second elseif cand then section. There are a few other functions I'd also like to add to it, which I was planning to do by trial and error, but if anyone has a bit of time to assist, I'd be most appreciative. Cheers, Number 57 21:36, 2 August 2020 (UTC)

cand and sc don't appear to be initialized by your code (Lua inits them to nil) and both are globals. Generally not a good idea to have globals if they can be avoided. Consider adding require('Module:No globals') at the top of your sandbox. It will help find (mis)used globals.
Trappist the monk (talk) 21:54, 2 August 2020 (UTC)

Hello Trappist. Thanks for your response at Wikipedia talk:Lua, but TBH I don't understand, as I don't know Lua at all (I have no idea what a global is). I saw someone else created this module (which is great) and want to widen its use. However, I don't know how to code it, so have just been messing around doing it by trial and error... If there's any chance you could fix it (if it's a quick fix), that would be great. Cheers, Number 57 22:11, 2 August 2020 (UTC)

It isn't clear to me what it is that you are wanting to do. If I preview the example templates at Template:Election results/testcases using the live template and module, I see what looks to be correct rendering. I added {{Testcase table}} to give side-by-side renderings.
What is wrong with the live version that you want changed?
Globals are items that have global scope – are visible and changeable (that's the dangerous part) from anywhere in the module. For safety and reliability, every function, table, and variable in a module should be declared local so that its scope is limited to where it is used. Stuff will still go wrong but the wrongness is usually confined to a smaller portion of the code.
Trappist the monk (talk) 22:46, 2 August 2020 (UTC)
I believe the issue with the sandbox is cand is never set to true, so rows are never populated. But, like Trappist the monk, I don't quite see what you're trying to do in the sandbox. ProcrastinatingReader (talk) 02:22, 3 August 2020 (UTC)
As as a comment about as I don't know Lua at all. Not sure how wise this is as you'll need to maintain this module and handle errors and feature requests. Just throwing stuff together until it works is almost never the correct thing to do. --Gonnym (talk) 06:39, 3 August 2020 (UTC)
@Trappist the monk: As a starting point, the current version in the Parliamentary testcases should ideally spit out something like the below.
Party Votes % Seats +/–
Kuomintang 5,813,699 71.88 50 +50
Democratic Progressive Party 2,274,586 28.12 45 –50
Valid votes 8,088,285 98.57
Invalid votes 117,160 1.43
Total votes 8,205,445 100
Registered voters/turnout 14,313,288 57.33
Source: CEC
@Gonnym: The module already exists. I'd just like to make it more flexible to deal with other types of elections or electoral systems. I can produce a list of features that would need to be incorporated to allow it to cover (probably) 95% of elections if that would help. Number 57 12:46, 3 August 2020 (UTC)
As an example of an issue you can run into. If the table above will be produced by the module then it's producing semantically incorrect rows (as the last 5 rows aren't header rows) and 2 of the columns aren't following MOS:ABBR and WP:HEADERS. These issues will make any page using this fail FA and should be fixed. Also, the sorting messed up the table. --Gonnym (talk) 12:58, 3 August 2020 (UTC)
What do you mean by 'semantically incorrect rows'? Perhaps you could show what a corrected version would look like? Number 57 16:04, 3 August 2020 (UTC)

Need some Lua help for Template:Subject bar

Could someone with Lua skills please look at this discussion:

--Timeshifter (talk) 10:12, 12 August 2020 (UTC)

Added what I think you're trying to achieve to the module sandbox. See testcases. ProcrastinatingReader (talk) 11:16, 12 August 2020 (UTC)
ProcrastinatingReader, Thanks! I will ask that your change be implemented in the module. --Timeshifter (talk) 12:01, 12 August 2020 (UTC)

Any way to see pages where my Lua module is throwing errors?

I've done a little searching on the Wikipedia Lua resources and I don't think this is possible, but it would be great if it was so I figured I'd ask: is there any way to see a list of pages that are throwing errors when running a Lua module? Specifically, I recently revamped the {{LDS}} template, which is used to cite to Mormon scriptures like the Book of Mormon, so that it calls a Lua module (LDSverse). It works great, but there were a few places where people were misusing the original version of the template in a way that would just create broken external links—aka errors that were invisible to the reader on Wikipedia—but now when those bad parameters are passed to the Lua module it tends to create one of those big red Lua script error messages in the middle of Wikipedia pages. I might change how errors are handled to make the module fail more gracefully, but ideally it would be nice to find the handful of pages that are causing the errors and just fix them.

So is there by any chance a page that lists all the instances of the module causing an error? Or any way to somehow (easily) create that? If not, no worries, but I didn't want to find out there is after putting in a few hours of other work! ― biggins (talk) 10:49, 27 August 2020 (UTC)

I'm not sure if there is a way to see where the errors are, but in general, if you know a way code that you write can produce an error (such as accessing a nil parameter), then your code should always handle it, regardless if there are current errors or not. I see you've added /testcaeses which is great, so try and think of how your code can break, and make sure you handle anything you find. Unrelated, it might be better to move the module to be the same name as the template, as is common. --Gonnym (talk) 10:57, 27 August 2020 (UTC)
I've been occupied elsewhere for a while and consequently have been very lazy. However, I often monitor Category:Pages with script errors using this link for errors in articles. A couple of days ago I saw some errors (at least two pages, maybe four) which were due to your change to use the module. After working that out, I wondered whether to alert you but decided not to because it can be a bit in-your-face to present a list of problems while you are part-way through a large update. That is, I decided to leave it for a day or two to see if the problem was fixed. That appears to have happened because there is nothing at the link showing an LDS problem now. The advantage of leaving the big red error message is that someone, perhaps me, will notice it and take action eventually. By contrast, some custom error message might never be seen except by occasional baffled readers. Johnuniq (talk) 11:00, 27 August 2020 (UTC)
One error in that list: Lua error: Book <bm/introduction> not found in Standard Works.. --Gonnym (talk) 11:09, 27 August 2020 (UTC)
You could try this search. It's currently not returning any results. Certes (talk) 11:12, 27 August 2020 (UTC)
The problem with using assert() to catch user input errors is that it makes it look like the module is broken so editors are going to shy away from such glaring error messaging; and if they do click that message they are presented with the drop-down that is helpful to the developer but not so helpful to the common editor. Take the time to create error messaging that is useful to the common editor; categorize the errors; provide help text and a link in the error message to that help text. Save assert() and error() for truly broken module code.
Of course, it is common for editors to blithely ignore error messages; they do it all the time with cs1|2 ... Still, no reason to shout at them.
Trappist the monk (talk) 11:53, 27 August 2020 (UTC)
Many many thanks for all the quick replies, that is all extremely helpful. @Johnuniq: the link you provided is pretty much exactly what I was looking for! And to all the good points made above, I'm torn between shouting at users so that they (and now I) can more easily recognize errors vs handling them more gracefully and inevitably letting errors go unseen and uncorrected for a long while. I will try to get at the best of both worlds. Also, I do plan to move the template to the same name as the module, but I both wasn't sure yet how to do that and wanted to make sure there was consensus to do so too since it looks like renaming/moving it was considered (long ago) and rejected. Anyway, thanks to you all again! ― biggins (talk) 12:56, 27 August 2020 (UTC)
I've fixed the pages named in that link except Yaroslavsky suburban railway line. No error message appears on the page, and I can't see any obvious faults. Can anyone solve the problem? Certes (talk) 13:19, 27 August 2020 (UTC)
You can find the error message in the html source:
{{rcr|MZD|Yaroslavsky}}Lua error: expandTemplate: template "MZD color" does not exist.
Trappist the monk (talk) 13:32, 27 August 2020 (UTC)
Errors in station articles (such as Yaroslavsky suburban railway line) pop up regularly and I have given up trying to solve them. Instead, I use "related changes" to find, for example, that Module:Adjacent stations/MZD (moved to Module:Adjacent stations/Moscow Metro and then to Module:Adjacent stations/Nizhny Novgorod Metro) was changed by AJP426 a week ago, then I alert them and they fix it. One more point: the error category can be weeks behind a change. Generally, if you edit a module and it breaks something, the error category will show a dozen or a few hundred errors within a few hours. However, after they are fixed, a trickle of other problems might appear in the category weeks later because it is only updated when pages are rendered. Johnuniq (talk) 23:44, 27 August 2020 (UTC)
This link may help.If you click on the error message in RED itself a cryptic Lua error summary can be viewed. Apologize if I have repeated some of the information found above. I also try to find if some change occurred on the page that may have initiated the error. -- Matroc (talk) 06:27, 28 August 2020 (UTC)

Speedy deleting a sandbox module

I would like to mark Module:Sandbox/davidwr/example2 as {{db-author}} but I don't think that will have any effect. What is the correct way to request speedy deletion of modules whose page name starts with Module/Sandbox/your userid/ and for which you are the only or primary author and which has never been outside of "your module-sandbox-prefix namespace"? I have blanked it.

I asked the question that way since obviously if another editor touched it, it's not equivalent to db-author, and if it's been in the "main" Module: namespace or it ever was there, others may be relying on it. davidwr/(talk)/(contribs) 20:37, 6 September 2020 (UTC)

It takes an extra step, but if you create a /doc with the db and a note saying you want the module deleted it will take care of both. Primefac (talk) 21:43, 6 September 2020 (UTC)
@Davidwr and Primefac: although it sometimes fails when the admin just deletes the newly-created doc page and not the module. It's happened to me more than once in the past. I've even tried using the talk page with the same result. The surest way is to ask a sympathetic admin to delete the unwanted module for you. I'm always happy to oblige if you ping me. --RexxS (talk) 02:25, 7 September 2020 (UTC)
True, though I should hope we've gotten to the point where the more overzealous "pay no attention to the reason behind the tag" admins have been desysoped. Same here with the deletion-on-request, for what it's worth. Maybe that should be a category? Primefac (talk) 02:46, 7 September 2020 (UTC)
@Primefac: You have some good points there. I have two proposals in reply: Proposal 1: Assuming most admins use scripts to assist deletions, putting in extra "do you also want to delete X, Y, or Z" buttons if there are any parameters might do the trick. (I am not an admin, so I can't see the tools.) Proposal 2: As for "deletion on request" perhaps a better idea would be to have a special template called "db-another-page" that users can put on their own talk page. In addition to allowing users to request deletion of Module: pages and for that matter things like .css and .js pages (say, to delete their edit histories), this would allow blocked users to do db-author and db-user requests and for that matter, certain other requests like db-copyvio and other requests that are "ignore all rules, deleting this is clearly in the best interest of the encyclopedia" even though blocked users shouldn't normally be making such requests. davidwr/(talk)/(contribs) 13:13, 7 September 2020 (UTC)
@Davidwr: I like the idea of {{db-other-page}}, especially as you'd need an interface admin to deal with your .css or .js pages. It would need to place the page in a category that is patrolled by admins, of course. The only downside I can envisage is placing the template on your talk page and then returning the next day to find your talk page deleted.   --RexxS (talk) 14:20, 7 September 2020 (UTC)
I would envision the template to look more like {{edit protected}} than a typical speedy-delete template, complete with the orange background when used on talk pages. davidwr/(talk)/(contribs) 14:25, 7 September 2020 (UTC)

Get a list of sysop by using Lua

I want to get a list of sysop in viwiki (Vietnamese Wikipedia). How can I do that by using Lua? Thank you! Alphama (talk) 03:30, 7 September 2020 (UTC)

I recall seeing someplace that Scribunto does not have access to the content of Special: pages. This seems to be confirmed because mw.title.new('Special:ListUsers/sysop'):getContent() returns nil. If you don't get an answer here, you might ask at WP:VPT.
Trappist the monk (talk) 10:52, 7 September 2020 (UTC)
@Alphama: You might be able to use the API, try something like this: https://vi.wikipedia.org/w/api.php?action=query&list=allusers&augroup=sysop. I don't know Lua well enough to know how to incorporate that into a Lua module, but worst-case you could use the API to generate a static lists of sysops, then use Lua to parse it. Form more help, see the "allusers" link under "list" in mw:API:Query. davidwr/(talk)/(contribs) 13:46, 7 September 2020 (UTC)
Lua can't access the APIs but has its own methods and functions. The most relevant is probably getContent() on a title object, but I don't think there is any way for it to read Special: pages. Certes (talk) 14:48, 7 September 2020 (UTC)
As mentioned, it can't be done. One way to think about it is that there is no method that would allow the software to know that a page using the module needs to be updated because a change in sysop status has occurred. That is, "what links here" on a page displaying sysop information will never (without major rewrites) point to an API or Special page as being the source of information required to render the page. Johnuniq (talk) 23:46, 7 September 2020 (UTC)
Hi guys. Thank you for your comments. I am working with the Ping group template, I want to take dynamically a list of admins and send them the ping message. However, it does not seem possible to use Lua to retrieve this list. I may try the other way. Alphama (talk) 03:03, 8 September 2020 (UTC)
You would use Javascript for that and could ask at WP:VPT. Johnuniq (talk) 06:36, 8 September 2020 (UTC)
Alphama, given the small number of sysops in viwiki and the presumed low turnover, it sounds like the easiest thing to do would be to create a static template then manually update it as part of the "paperwork" that goes with granting or removing the sysop bit. Heck, you could do the basic coding in Lua and have it ping everyone that is listed in a static wiki page. Just keep that page and the module protected :). davidwr/(talk)/(contribs) 15:36, 8 September 2020 (UTC)
I did it already [2] but I want to find a "write-once-use-permanently" method. Alphama (talk) 23:23, 8 September 2020 (UTC)
Does viwiki have a bot that can regularly download a special page and upload its content as a non-special page for Lua to access? If so then that could also be a solution. If not then you may find enough other uses for the bot to make it worth installing. Certes (talk) 15:59, 8 September 2020 (UTC)
It is also a helpful solution. However, in that case, we need to run this bot so often. The best solution is to write a small code so that it can get the admin list automatically, then we can reuse this list for any purpose. Alphama (talk) 23:23, 8 September 2020 (UTC)
I looked deeply into getting portals to read category membership, which is a similar task. The consensus at VPT after several discussions such as this was that it can't be done because of Lua restrictions, and that a bot might be the least bad solution. Certes (talk) 09:36, 9 September 2020 (UTC)
Possible outline of a general simulation to allowing modules to process special pages:
For special pages whose changes are logged, such as user-rights changes, have a bot check the log every minute/hour/day/week and update a static list. The static list is a recent "snapshot in time" of the special-page.
For special pages whose changes are not logged, decide how "stale" the data can be and have a bot re-create that page on a fixed schedule. Or, have an auxiliary script that humans, or, ideally, modules can use to kick off the bot to run "on demand." davidwr/(talk)/(contribs) 19:49, 9 September 2020 (UTC)
We can learn from JL-Bot 5, which operates by checking pages for a dummy template and replacing what follows it by content as requested in the template's parameters. So adding {{Somebot|subst|Special:ListUsers/sysop}} to a page might make a current list of sysops appear after it whenever Somebot runs, just as if {{subst:Special:ListUsers/sysop}} did what we might naively expect it to do. Certes (talk) 20:48, 9 September 2020 (UTC)

Modules

I cannot edit any modules, Module:Sandbox/Gioguch/temp doesn't work. It gives you errors and does not let you publish. Can you give me some valid Lua text so I can test? Gioguch (talk) 02:19, 22 September 2020 (UTC)

I was able to save a one-liner consisting of only a comment at that page. For examples of Lua text, see any existing Lua module. Module:Example is a good place to start. davidwr/(talk)/(contribs) 02:49, 22 September 2020 (UTC)
And more than one line:
{{#invoke:Sandbox/Gioguch/temp|add|1|2}} → 3
{{#invoke:Sandbox/Gioguch/temp|sub|1|2}} → -1
Trappist the monk (talk) 02:59, 22 September 2020 (UTC)

Small wikis and lua

Hello from el.wiktionary. Small wiki projects: 2-5 lonely editors, who most of the time know nothing about wikitext, lua and all that. But we find semi-finished modules, also the tasks demand some technical knowledge.
It seems that there is no wiki-support for us. I have tried at mediawiki in vain. Our great friend Erutuon has helped us immensely, but we cannot bother one person all the time.
The idea would be, a 'suitcase' of not complicated, friendly, copypaste modules and templates for the needs of wiktionaries, of wikipedias, of wikiwhatever. No jargon explanations, but real life examples. I have tried in a very naïve way, a suggestion of what we need at el:wikt:User:Sarri.greek/Learn_Lua_and_wikitext. Are there any Lua writers who would like to write such a textbook? Where could I petition for a board of Lua support? Psychologically, it feels uncomfortable to seek help from outside, something boring, irritating to experts. It should have been, I think, a regular and normal thing to have an umbrella support. Thank you for listening. Sarri.greek (talk) 20:37, 11 October 2020 (UTC)

It's too hard to write documentation that would be useful because people have such varied backgrounds. Wikipedia:Lua/Resources links to what is known. However, anyone who wants to learn Lua should install it on a computer and play with it while studying its documentation. Most questions that are asked here get good replies which often helps people overcome barriers. Johnuniq (talk) 22:04, 11 October 2020 (UTC)
Thank you Johnuniq The module-tasks e.g. in wiktionary are the same for all wiktionaries. 10 to 20 modules would suffice. The editors would just need to 'change the words' for their language. I do not wish to become a car mechanic, I just want to drive a car. Sarri.greek (talk) 22:14, 11 October 2020 (UTC)
and I am reading your User:Johnuniq/index very nice, indeed. Sarri.greek (talk) 22:26, 11 October 2020 (UTC)
Try precisely describing a problem and someone here might help write a solution or guide its creation. What's needed is a proposed syntax with an example of what wikitext would be on a page, together with what output it should produce. Any examples would help. Johnuniq (talk) 22:35, 11 October 2020 (UTC)
Yes, @Johnuniq: but, who are the people I could ask? e.g. you are in en.wikipedia. Why should you have to answer to xx.wikixxxx questions... Ok then: [3].. Sarri.greek (talk) 23:04, 11 October 2020 (UTC)
I would need something more precise, with an example. Is el:Template:yy the actual template or is yy an example? Give some pages as examples and say what the wanted output would be. A big-picture question is whether en:wikt has a method of handling whatever you are trying to do. If so, why not use it? If not, why don't they? Johnuniq (talk) 01:45, 12 October 2020 (UTC)

They? There were 2 lua people back in 2015. Gone for some years now. Never mind, forget it. Sarri.greek (talk) 02:07, 12 October 2020 (UTC)

So what, if anything, is used at en:wikt? People here, including possibly myself (depending on job complexity and my real life), may help but I would need a worked example which makes understanding much easier. Johnuniq (talk) 02:45, 12 October 2020 (UTC)
I am studying your work @Johnuniq:. I would love to ask you some short questions, but I do not wish to take up space in this friendly page.
It is difficult to go from Hello world and Frère Jacques straight to Beethoven's 5th symphony. The complexity of en.wikt modules means that we cannot use it as model. Sometimes I go to History, back to 2017 to get easier versions of the same modules. If one could review notes for rookies, correct the misconceptions and answer simple questions, block by block, it would help a lot. For instance, you do not enclose your modules between local export = {} ... return export. How does this affect the way one writes the various commands? Should I correct this structure? The variety of styles of luawriting is very confusing to rookies. Could I ask little questions like that somewhere? Something like a LuaSchool. I promise not to bother you too often. Sarri.greek (talk) 08:12, 12 October 2020 (UTC)
Sure, ask questions, that's what this page is for. If you ask here, other people might offer their views and/or learn from the answers later. If you ask somewhere else, we might be the only people to see it. Regarding my style of returning a table defined at the end, one or two others do it that way. Most people just follow the cookbook which is to use p (not "export") and don't it give it much thought. Sometimes a module will have lots of functions defined in p, when only one or two of them are needed. I hate that because long programming experience leads to the certain knowledge that anything exported will be used by someone, and then if you ever change it, breakages will result. Also, if there are a dozen functions defined in p, anyone wondering how to use the module will waste time trying to work out if the exported functions should be used. I like the explicit nature of the table defined at the end which says exactly which functions should be used, in one place. When debugging a module using Scribunto, you can use p to refer to the exported table. You cannot use "export" or any other name. On a general "learn Lua" page, I would be inclined to use p for simplicity. I believe "p" is a convention for "package", as in a package of exported functions or data. Johnuniq (talk) 08:26, 12 October 2020 (UTC)
I made a start on Scribunto: An Introduction, a book aimed at wiki editors unfamiliar with programming or with Lua. Unfortunately, it remains only about 10%-20% done, but perhaps what is there may be of some use. — Mr. Stradivarius ♪ talk ♪ 13:42, 12 October 2020 (UTC)
Thank you thank you @Johnuniq: for your very detailed and complete explanations. / sorry I did not get a ping, and I am surprised that everyone replies! I am not used to it /
@Mr. Stradivarius:!!!!!!! I have been reading your book. And I am indebted. Apart from the debug console, which i do not use, your texts, were so englightening (about conerting or not, etc). A LuaSchool would be nice, if people up above think it useful. Phililogists and experts on their fields, will never sit down to become Lua programmers. They would just need to understand a few things. Pages like Lua.Ref.Manual may be very ... inclusive is the word? -excuse my english- but your book was much more help to me. I wish this project went on. Thank you Sarri.greek (talk) 15:45, 12 October 2020 (UTC)

table a b c

Excuse my ignorance. I have this little table: local fruits = {"apple", "melon", "orange"}
Now, I want to say: if thisparameter is one of the things belonging to local fruits, do so and so. What do I have to write? Sarri.greek (talk) 19:47, 12 October 2020 (UTC)

You can rewrite the table:
local fruits = {["apple"]=true, ["melon"]=true, ["orange"]=true}
then:
if fruits[thisparameter] then <something done here> end
You can:
local fruits = {"apple", "melon", "orange"}
for _, fruit in ipairs (fruits) do
    if fruit == thisparameter then <something done here> end
end
Trappist the monk (talk) 20:00, 12 October 2020 (UTC)
o! wonderful, thank you Trappist the monk Sarri.greek (talk) 20:19, 12 October 2020 (UTC)

Module:Automatic archive navigator on bnwiki

Recently i imported Module:Automatic archive navigator on bnwiki and as excepted half of module doesn't work because module needs input in en digit but its getting input in bn digit. Also this module is invoking other two module, i am not sure how to fix. I explained everything here. Please take a look. --আফতাবুজ্জামান (talk) 00:38, 13 October 2020 (UTC)

One thing you might do is look around at bn.wiki to see if someone hasn't already written a digit conversion module – I would be surprised if one doesn't already exist. I have seen them; don't know if it was at bn.wiki or elsewhere.
Trappist the monk (talk) 00:44, 13 October 2020 (UTC)
formatnum can deal with Bengali numerals if run in the Bangla locale. Does that help? Certes (talk) 00:52, 13 October 2020 (UTC)
Yes, there is a module, bn:মডিউল:সংখ্যা রূপান্তরকারী. It can convert en to bn & bn to en digit. I am not sure where to apply this in the code. --আফতাবুজ্জামান (talk) 01:07, 13 October 2020 (UTC)
@আফতাবুজ্জামান: I've made some edits to the modules on bnwiki corresponding to Module:Automatic archive navigator and Module:Highest archive number that should fix the problem but I find it somewhat difficult to test since I don't speak Bengali, could you confirm it now works? * Pppery * it has begun... 01:59, 13 October 2020 (UTC)
@Pppery: Yes, It's working. Thank you. --আফতাবুজ্জামান (talk) 02:12, 13 October 2020 (UTC)

Custom argument values in Module talk:Infobox military conflict

Hello, I reuse this module for viwiki. I would like to use both English and Vietnamese parameters:

  • self.args.image and self.args.hình_ảnh // I have a error for "hình_ảnh"

How can use this? Thank you. Alphama (talk) 14:40, 26 October 2020 (UTC)

What is the error? The // is not valid in Lua. Did you try:
if self.args.image or self.args.hình_ảnh then
and:
image = self.args.image or self.args.hình_ảnh,
Trappist the monk (talk) 14:52, 26 October 2020 (UTC)
The Vietnamese parameter needs to be wrapped in brackets and quotes, like so: args["hình_ảnh"]
The same should be done with any other Vietnamese parameters with non-english and non-latin characters. This is a quite common thing that needs to be done with translated parameters.--Snaevar (talk) 18:42, 26 October 2020 (UTC)
@Alphama: Lua allows "syntactic sugar" for several constructions to let programmers use syntax that they are familiar with. A common example is tbl.par which is equivalent to tbl["par"], which makes a string keyed ("par") value in a table (tbl) look like a property (par) of an object (tbl). Unfortunately, that bit of sugar often doesn't work when the string key is not a simple string of alphanumerics. For example tbl["a-1"] works fine, but tbl.a-1 causes an error. As Snaevar says, that means you can't use the object.property style of syntax when "property" contains Vietnamese characters. --RexxS (talk) 19:08, 26 October 2020 (UTC)
But ... According to mw:Extension:Scribunto/Lua_reference manual:
String keys that are also valid names may also be accessed using dot notation, e.g. table.key is equivalent to table['key'].
and names are defined as:
A name (also called an identifier) in Lua can be any string of letters, digits, and underscores, not beginning with a digit.
That appears to be a loosely quoted extraction from the Lua Reference manual §2.1 which reads:
Names (also called identifiers) in Lua can be any string of letters, digits, and underscores, not beginning with a digit. This coincides with the definition of names in most languages. (The definition of letter depends on the current locale: any character considered alphabetic by the current locale can be used in an identifier.) Identifiers are used to name variables and table fields.
Wouldn't ì (U+00CC LATIN SMALL LETTER I GRAVE) be a letter in the vi.wiki locale? Is the documentation wrong? Does Scribunto impose an apparently non-Lua restriction on wikis that aren't normally written using just the ASCII character set?
Trappist the monk (talk) 19:48, 26 October 2020 (UTC)
@Trappist the monk: Go to https://www.lua.org/cgi-bin/demo and try the following code using ì (U+00CC LATIN SMALL LETTER I GRAVE) as part of an identifier:
t = {}
t["aì"] = 123
print( t["aì"] )
When you run the code, you'll see it behaves properly as expected. Then try:
t = {}
t. = 123
print( t["aì"] )
and run the code. You'll see that it's the implementation of Lua (not just Scribunto) that fails to translate t.aì to t["aì"]. Change the ì to i and it all works fine. If you want to be certain of using object.property as an alias for object["property"], then you have to restrict the characters in the string "property" to [A-Za-z0-9_]. --RexxS (talk) 20:18, 26 October 2020 (UTC)
Maybe yes, maybe no. Clearly, https://www.lua.org/cgi-bin/demo is an English language website so its locale may (seems that it does) specify an ASCII-only character set. If not Scribunto then but possibly MediaWiki? I would think that to the typical vi.wiki user, ì would be alphabetic so when the Lua manual says that "any character considered alphabetic by the current locale can be used in an identifier", were I a vi.wiki editor, I would expect the Scribunto installation at vi.wiki to allow letters that are routinely used in the language. ì is not routinely used in English so it does not surprise me that t.aì does not work at the lua.org demo or here.
Which brings me back to my question: Is the documentation wrong? If it is intended that all Scribunto installations accept only the ASCII character set for names, then shouldn't mw:Extension:Scribunto/Lua_reference manual actually include that information in the list of Differences from Standard Lua if nowhere else?
Trappist the monk (talk) 21:54, 26 October 2020 (UTC)
A confounding factor is that Scribunto is based on Lua 5.1 but has some enhancements from 5.2. According to some posts found in Google, Lua has dropped "The definition of letter depends on the current locale..." after 5.1. That is seen in the manuals: Lua 5.1 + Lua 5.2. Lua does things differently from many other languages but allowing non-ASCII in identifiers would be a step too far IMHO and regardless of what the Scribunto docs say, trying to use that feature (if it exists) is doomed to fail. We should probably ping Mr. Scribunto or ask at Phabricator, or just ask at the doc talk. I would say the docs should be tweaked. Johnuniq (talk) 22:54, 26 October 2020 (UTC)
Then let us summon Mr. Scribunto. --Izno (talk) 02:48, 27 October 2020 (UTC)
Not my job anymore. Scribunto on all Wikimedia wikis should be using the "C.UTF-8" locale (see also T107128), unless someone broke things, where the definition of a "letter" is the ISO basic Latin alphabet. But other wikis using Scribunto might be using different locales (see mw:Manual:$wgShellLocale). Anomie 17:55, 27 October 2020 (UTC)

Can you check the locales of viwiki? Alphama (talk) 13:48, 29 October 2020 (UTC)

  Idea: Should we do something like multilingual parameters when we build Lua modules so that other projects can inherit these easily from English Wikipedia? In my case, I prefer to use three parameters at the same time ("image", "hình", "hình ảnh") so I need to convert the template back to the old method, without using Lua module. Alphama (talk) 00:38, 27 October 2020 (UTC)

Db-multiple

Picked {{Db-multiple}} off Wikipedia:Lua/To do. See Module:Sandbox/ProcrastinatingReader/Dbm and demos at User:ProcrastinatingReader/Dbm. Biggest improvement is probably that it can now handle per-criterion arguments (rather than passing rationale to each one). I think it replicates all of the functionality of {{Db-multiple}}. Would like to add support for custom templates of the same CSD cat, like {{db-copypaste}}, at some point. Code is pretty messy, trying to get around some weirdities of Lua, and there's probably a neater way to do a lot of the stuff.

Usage as such:

{{#invoke:Sandbox/ProcrastinatingReader/Dbm|main|G6|rationale{{=}}leftover redirect following move of own sandbox into userspace|G7}}

Thoughts? ProcrastinatingReader (talk) 15:52, 20 September 2020 (UTC)

I fail to see the point of this. What problem is actually solved by converting this template to Lua? * Pppery * it has begun... 15:57, 20 September 2020 (UTC)
Biggest improvement is probably that it can now handle per-criterion arguments (rather than passing rationale to each one). -- see sandbox demos, current CSD repeats rationale for all criteria, and in deletion summary also, even if it doesn't apply to said criteria. Also see db-meta archives (1, 2) re converting it into lua. ProcrastinatingReader (talk) 16:01, 20 September 2020 (UTC)

Updated the module to annotate the code better, so hopefully it's less of a mess to follow, and simplified a few things. would someone be able to code review this? ProcrastinatingReader (talk) 18:03, 6 November 2020 (UTC)

Module:Progression rainbow

Could I get a code review and/or have the questions I've asked in the module? I'm learning and not entirely sure about some things. --Izno (talk) 17:09, 4 November 2020 (UTC)

I guess I'll comment here since the module talk page redirects to template talk. The module looks good although I haven't fully checked the overall logic. Some rather inconsequential thoughts follow.
  1. Suggest remove space after require (twice). It's just a function.
  2. I originally used underscores such as in class_percent per Python conventions. However, I've switched to camel case (classPercent) as that is the dominant style here.
  3. Re if remaining ~= 0 then, I would write if remaining > 0 then for that kind of condition on the basis that you would not want to execute the following code if remaining somehow ended up negative.
  4. "Is there a way to avoid passing a reference to the parent frame?"
    • _main could keep its frame parameter and use frame = frame or mw.getCurrentFrame(). That would make frame optional.
  5. In local classes = { ... } I would put a comma on the last item. That's a personal style thing but it makes diffs much cleaner in the future when things get added or shuffled around.
  6. Re object-orientation, some write classes in modules but I rarely find them useful. The beauty of Lua is its simplicity and implementing classes often obscures code IMHO. I'm talking about typical modules—of course classes are great in other situations. I'll dig up some links to examples if you like, but they are very heavy reading.
  7. "is there a more idiomatic way to initialize project?"
    • It's not idiomatic, but I love the function I use for this: stripToNil. Your if...end would be replaced with project = stripToNil(args['project']). See Module:Age. People come up with various funky ways of handing this, the worst of which is repeating the code every time it's needed. Some use functions with names like isEmpty.
  8. Re for i, class in pairs(classes) do, I recommend ipairs not pairs. For one thing, ipairs will generate the items in a defined order which doesn't matter here but is normally wanted. Also, if you ever added an option to classes like example = true, you wouldn't want it to turn up in pairs. Finally, use _ rather than i because that variable is not used and underscore is the convention for "intentionally not used".
  9. Code like class['count'] is Python. It's really convenient to use Lua's equivalent class.count which works provided count is a valid Lua identifier.
  10. Re the "parameters 1 to 8" comment and following loop, using ipairs would be better. Use if i < 9 then to skip the inner code for 9. Using tonumber(args[i]) will give nil when someone enters a non-numeric parameter and that will give a mysterious run-time error when the addition in the next line occurs. I would either append or 0 so it doesn't crash, or or error('Need a number', 0) to give a clue.
  11. "what is the more friendly way for i18n?"
    • There is no good way and people devise various solutions. The problem concerns the merits of i18n vs. readability of code. A blue-sky scheme is underway somewhere (not at enwiki) that I can't find at the moment with ideas about having a central list of templates/modules with i18n subpages and klunky syntax. Module:Age was wanted at bn:Module:বয়স so I put an mtext table at the top—pretty crude but I didn't want the overhead of requiring a subpage particularly when I wasn't sure it would ever be used.
  12. Re "if p._main should be stringified", aren't all the items in the concatenation strings? I'm not sure what is meant. If you mean, should you return root rather than tostring(root), I believe Scribunto will apply tostring to the return value (although it turns nil into an empty string, I think) so in principle it doesn't matter. I would make it explicit.
  13. Re "how to add \n before", I would use your method.
By the way, if you examine the HTML to check the output, try using Module:Dump by previewing wikitext like
{{#invoke:dump|dumphtml|1={{Progression rainbow|20|20|100|40|30|40|10|40|310}}}}
Johnuniq (talk) 06:45, 5 November 2020 (UTC)
Here is quite alright for me personally! Numbered for ease of reference.
  1. Of course.
  2. This is also C++ std library and core guideline convention, and Rust convention, if no others, and I prefer the_look to camelCase for functions and variables at least, I think. I reserve the right to change my mind. ;) I will peruse the style guide also, which I maybe should have looked for.
  3. I'll ponder that. Mine was a port from wikitext where that was the condition, which of course is why I marked it as "uhhh".
  4. Hmm, the point was to remove the parameter in the function API if I can. That suggestion seems to retain it? (You did not really explicitly say "yes, Izno, you have to retain that" :).
  5. I rarely have an issue seeing past the noise with WP:WikEdDiff. Even then, I'm used to leaving the trailing delimiter out, from CSS.
  6. Oh, I definitely think object orientation in this module is the wrong solution. Mostly an idle curiosity on my part.
  7. Cute implementation. It seems heavier weight to stand up the pattern than to check for existence and non-emptiness though? (Yes, I realize this is a premature micro-optimization in this context.) (I wish we had a good means to profile; looking at the HTML output source is rough enough.)
  8. Okay, in the first instance (which I believe is your context), it makes sense I think.
  9. Oooh, I'll do that for the text lookups, but the way the Lua book frames it I can't do that with the index lookups. (I think I made a conscious decision to be consistent but I'm not bothered by that too much here since there are only two places where the index lookup is used right now.)
  10. The most interesting of my questions to me. :) I did deliberately want to skip an explicit conditional that comes with the more rangey/generic for loop; maybe the expressiveness is worth it? Nil: I assume you mean non-number-looking value here, but taken on board.
  11. I was more asking about e.g. a C printf command so that I can store the text separately. I know that Module:Citation/CS1/Utilities (I think it's in that one) has set_message and I see message in Module:Age with somewhat different implementations (though I haven't looked at the real differences). Re 'actual' i18n, there's efforts today for Module:I18n and Module:TNT; the latter was spawned from looking for Today solutions for phab:T52329. (Re separate page, loadData is of interest for those readers who don't know it for a reason to put a table of strings on a separate page instead.)
  12. I am fairly certain that root is a table, not a string, since the example on the reference manual is to return it as a string, but I have nothing to base that on myself. :) (Maybe something to review.) I mean more for its interaction with p.main, if relevant or interesting.
  13. Ok.
I mostly used the /testcases page to sort that out anyway since I needed to reproduce the then-wikitext implementation rather than starting from scratch (and only occasionally needed to review the HTML; most of the time I was stuck with nothing of interest displaying :). I did actually use Dump to inspect the Lua blobs of interest when I got to a certain point. --Izno (talk) 20:57, 5 November 2020 (UTC)
@Izno: I just noticed this and haven't got the strength yet to comment at length, but I'd reinforce Johnuniq's advice in #10 to use ipairs whenever you want to traverse the sequentially indexed keys in a table. It avoids unexpected errors when other keys might be included and it produces a consistent, reproducible order for the loops.
It's also worth repeating that tonumber(x) returns nil whenever it can't cast x into a valid number (unlike some other less weakly-typed languages that will return 0). My advice is to always explicitly enforce typing for any function that can return nil: for example, using val = tonumber(x) or 0 will ensure that val always carries a numeric type, so won't throw errors if it is later used somewhere that insists on receiving a numeric value. My philosophy is to manage errors as gracefully as possible in production code. Editors using your code really get irate when readers see big red error messages, which should be for developers only. Cheers --RexxS (talk) 23:54, 5 November 2020 (UTC)

Re #2 (style), I'm very sympathetic to underscores but the thing that persuaded me to jump ship was that the Scribunto Lua code (viewable from mw:Extension:Scribunto) uses it, apparently on the basis that it complies with JavaScript conventions which is the other scripting language used here. I confess to ignoring some of the other Scribunto source conventions.

Re #3 (if remaining > 0), I adopted that strategy years before seeing Lua but I'm fairly alone.

Re #4 (frame), function _main uses it twice: frame:expandTemplate{...} + return frame:extensionTag{...}. You could remove parameter frame and use local frame = mw.getCurrentFrame() to get it, but that is pointless overhead. If you want _main to be usable by another module which might not want to bother passing frame, you would use what I wrote at #4 to make frame optional. You must use frame to call either of those functions. The reason is that the various magic words such as {{PAGENAME}} that might be used in the functions use the values from frame.

By the way, using frame:expandTemplate{...} without parentheses is using a baffling trick in Lua. Inserting parens is easy and reduces the puzzle factor for those reading the code. More importantly, using parens is consistent with other usages where they are required.

Re #5, fair enough but I will point out that redundant trailing commas have been common in many programming languages since at least the 1970s when C was introduced. They are very common in modules.

Re #7, Lua is astonishingly fast. Have a look here and its talk to see 1178 calls to {{convert}}. The HTML source includes "Lua time usage: 1.312/10.000 seconds". Now look at the omg ugly code in Module:Convert and the two enormous modules that it uses. The speed is breathtaking. It is possible to write inefficient code that tries to do too much (mainly calling expensive functions), and those modules can hit the 10 second limit.

Re #9, given t = {a=11, b=22, 33}, you could use t['a'] or t.a to get 11, but only t[1] can get 33 (because 1 is not a valid Lua identifier). Further, as you say, given local x = 'a', t[x] is the only way to get 11; t.x would give nil because t has no entry for x. Re consistency, the definition given for t works in Lua but not something like Python (using its standard syntax). Using t.a is consistent with a=11.

Re #10, a few years ago I would have agreed that having an expression in a loop was inefficient and ugly, but I've decided (particularly in Lua where the inefficiency is inconsequential) that "say what you mean" is good.

Re #11, I imagine you know that string.format is almost the same as printf. Module:TNT was what I was thinking of. We'll see how that turns out but when I last looked, the only examples had trivial code. They have listed Template:Convert as proposed for TNT but that's a bit of a dream IMHO (convert handles some unbelievably complex language weirdness that could not be put in a translation table).

Re #12, root is a table. That could be checked by putting assert(type(root) == 'table') somewhere in the code (without saving), then previewing with a page that calls the module. To test that the assert works, change 'table' to, for example, 'string'. Johnuniq (talk) 04:20, 6 November 2020 (UTC)

I get a sense of old man grumbles in some of that blurb. ;) I think most of that is read-only. I've adjusted per agreeable comments. Probably the one item of note is that I couldn't get for i, class in ipairs(classes) do to take args instead of classes using the iterator, so still not really showing that I'm trying to fill in from args 1 through 8. There is a sandbox and testcases if interested. (It's somewhat academic as the current code works.) Thank you for the reviews! --Izno (talk) 07:47, 6 November 2020 (UTC)
Re new comment about tr/td, you should insert tag tr. As the comment says, something like Remex is fixing the missing tr. It's not Scribunto because a dump of what the module produces shows that tr is missing but the HTML source shows it is present. An example of correct tags and indents is in Module:Navbox: see renderAboveRow.
There is one remaining pairs which might as well be ipairs. I think your for i, class in ipairs(classes) do loop is good; it's very clear that it is getting arguments. Johnuniq (talk) 09:39, 6 November 2020 (UTC)