generating unique IDs
Here is the requirement: some template needs to assign ID attribute (e.g., in order to use mw-customtoggle-<unique-suffix>). Now, this template might appear multiple times in a page, and each one should have a unique ID (for practical reasons, and in order to have valid HTML). Is there a sane way to ensure that consecutive calls (from different invocations) to the same code will return different results? for obvious reasons, having multiple elements with same ID is not only "invalid html", but also dysfunctional. Did anyone encounter similar challenge before? i hope someone can show me i am stupid, and there's safe and simple way to do it. thanks, peace - קיפודנחש (aka kipod) (talk) 17:45, 18 February 2022 (UTC)
- Use
math.random( m, n )
to get pseudorandom number and modify it for the id. — Jts1882 | talk 18:00, 18 February 2022 (UTC)- thanks for the advice, but unfortunately, it's not really good: the issue revolves around seeding, Math.random() reseeds on every call, which practically means it's not "pseudo random". if i could guarantee that each call will be executed in a different timeslice, it would work, but even then, the "pseudo random" is just a screen of smoke, and i could just as well use directly os.clock() modulo something.
- by reseeding every time, random loses its randomness. calling mw.math.random directly also does not work - when not seeded, it always begins at the same spot. to see what i mean, visit User:קיפודנחש/sandbox: i created a tiny Module:Testrand to demonstrate how consecutive calls to math._random() can return the same value (when the clock did not tick between calls). this happens because each call re-seeds, using the clock, plus some slow moving counters.
- admittedly, the parser is (currently) slow enough, such that on consecutive invocations the clock is "guaranteed" to move, but this approach is short-sighted.
- allow me bore you with "old-timer" story (personal experience, but i searched and found a link which discusses it): somewhere in the 1980s and 90s, there was a popular development tool called Borland Pascal. now, this product was meant to run on ms-dos, IOW, with no operating system whatsoever for anything other than file access.
- the lack of OS created a need for a "delay" library function (e.g., when you wanted to operate some hardware, like UART and such).
- BP implemented "delay" in a very naïve and straightforward way, which was reasonable then and would be crazy now: they ran some loop with junk code (or maybe even empty) N number of times, based on the parameter. to translate the parameter of delay() in MS to the number of times the loop should run, a factor is needed, which depends on the speed of the machine.
- so, as part of the initialization of the library, a "delay calibration" code was run: the loop was executed large number of times (~64K iirc), the RT clock was sampled before and after to determine the time it took, and divide 64K by the time to get the "delay factor" (so "delay" would execute the loop ms*factor times).
- when computers became fast enough, the "delay calibration loop" started executing faster than the clock resolution, and started throwing "divide by zero" exception.
- this happens only once, but unfortunately, this one time is during initialization, which basically meant that any program written in BP would fail to start on faster computers (at least, "fail to start reliably" - if you get lucky, your loop straddles a tick...). the sad part is the fact that it did not matter if you ever used or wanted to use "delay()" - vast majority of programs never did, and programmers who did not deal with hardware were typically not even aware of this !@#$% delay, but the "sudden death" affected everyone anyway.
- luckily for me, i worked at a large enough company at the time, and we had access to the library source, which allowed me to patch the library (i could not simply remove the calibration, since i needed "delay" to work, as my thing did interface with hardware).
- this story is only 12% relevant, but i enjoyed telling it, and i hope some of you enjoyed reading it. won't be surprised if some had first-hand acquaintance with it...
- the moral of the story is, do not rely on clock ticks between calls your program makes - some day someone will build a machine fast enough, and you'll find the clock did not tick between the first and 2nd call. under the surface this means that math.random is deeply flawed, as my sandbox demonstrates (BTW, this can be easily fixed: keep a module-wise local variable and ensure that seeding only happens once per invocation).
- going back to "random" (not in module math, but in scribuntu: mw.math.random): if it was possible to seed it once per wiki page parsing, such that consecutive calls continue to develop it without seeding, i was fine with going this route, even though there is no guarantee that N consecutve calls will return N distinct value for any N > 1.
- however, scribuntu creates a fresh "sandbox" for each invocation, which means random should be seeded per each invocation, which only works when the servers are slow enough, or when mw code is inefficient enough to ensure at least one tick between invocations.
- peace - קיפודנחש (aka kipod) (talk) 20:24, 18 February 2022 (UTC)
- By design, different calls with the same parameters are supposed to be totally independent of each other so, for example, one section can be parsed without regard for what is in other sections. I think there should be some restricted method of defining page-global variables (for example, to say "use mdy date formats on this page"), but without that I don't think there is any way of guaranteeing different results with the same parameters. Johnuniq (talk) 22:33, 18 February 2022 (UTC)
Lua error with Taxonbar?
Can anyone see what the issue is with this taxonbar for Gea eff (Q4281852)? When I type {{Taxonbar|from=Q4281852}}
, I see:
Lua error: bad argument #1 to 'getEntityIdForTitle' (string expected, got nil).
Backtrace:
- [C]: in function "error"
- libraryUtil.lua:11: in function "checkType"
- mw.wikibase.lua:144: ?
- (tail call): ?
- Module:Taxonbar:475: in function "chunk"
- mw.lua:525: ?
- [C]: ?
Thanks! Not sure if I should be asking here or Template talk:Taxonbar so I'm asking both places but will respond in both places when the issue is solved. Umimmak (talk) 04:58, 25 February 2022 (UTC)
- I don't know why it occurs, but the problem is that the following gives nil
mw.wikibase.getSitelink('Q4281852')
- and that makes Module:ResolveEntityId#L-12 crash with the error shown. Johnuniq (talk) 07:01, 25 February 2022 (UTC)
- @Umimmak: Now that I've had a chance to look at d:Q4281852, the problem is obvious. That item has no entry for enwiki in the "Wikipedia" section near the bottom. Therefore the title at enwiki is nil, and the confusing error results. Module:ResolveEntityId should handle that more gracefully, or at least give an error indicating what the problem is. Hmm, I see Module talk:ResolveEntityId mentions errors in hundreds of articles. The error has temporarily gone away because a recent edit at Module:ResolveEntityId was reverted. Johnuniq (talk) 08:30, 25 February 2022 (UTC)
- (edit conflict)@Johnuniq: hrm… this didn’t use to be an issue. I’m not sure why there needs to be a Wikipedia article for me to get information from Wikidata; I’ve definitely found it useful to have access to the taxonbar when I’m working on an article in a sandbox or draftspace. … but at least it’s working now? Umimmak (talk) 08:31, 25 February 2022 (UTC)
- I was reporting the situation from the point of the module: the "obvious" in my comment was referring to how the code in Module:ResolveEntityId would obviously give that error given that there is no enwiki article for that item. However, the code with that problem has been reverted, so yes, it's working now. I'm sure that if the module is updated again there will be some fix. Johnuniq (talk) 08:36, 25 February 2022 (UTC)
- (edit conflict)@Johnuniq: hrm… this didn’t use to be an issue. I’m not sure why there needs to be a Wikipedia article for me to get information from Wikidata; I’ve definitely found it useful to have access to the taxonbar when I’m working on an article in a sandbox or draftspace. … but at least it’s working now? Umimmak (talk) 08:31, 25 February 2022 (UTC)
- @Umimmak: Now that I've had a chance to look at d:Q4281852, the problem is obvious. That item has no entry for enwiki in the "Wikipedia" section near the bottom. Therefore the title at enwiki is nil, and the confusing error results. Module:ResolveEntityId should handle that more gracefully, or at least give an error indicating what the problem is. Hmm, I see Module talk:ResolveEntityId mentions errors in hundreds of articles. The error has temporarily gone away because a recent edit at Module:ResolveEntityId was reverted. Johnuniq (talk) 08:30, 25 February 2022 (UTC)
This was caused by a recent edit to Module:ResolveEntityId which I have just reverted — Martin (MSGJ · talk) 08:37, 25 February 2022 (UTC)
- @Johnuniq, Umimmak, and MSGJ: I think I resolved the issue at Module:ResolveEntityId/sandbox. Please test out {{taxonbar/sandbox}} and let me know. --Ahecht (TALK
PAGE) 00:16, 26 February 2022 (UTC)- @Ahecht: There is no wikipedia article (yet) for Gea africana and
{{Taxonbar/sandbox|from=Q2158509}}
yields:
- @Ahecht: There is no wikipedia article (yet) for Gea africana and
Authority control not recognising accented letters as letters
Please see Template talk:Authority control/Archive 13#TLS identifier format. We need some regex that will recognise accented letters are being letters. Thanks — Martin (MSGJ · talk) 15:18, 7 March 2022 (UTC)
- Consider changing line 823 to
local idlen = mw.ustring.len (id)
- Count unicode characters, not bytes.
- —Trappist the monk (talk) 15:44, 7 March 2022 (UTC)
No_globals issue solving
Over at Module talk:BaseConvert § convert with 'Module:No globals' error?, I have reported an issue (re 'No globals'), and a /sandbox solution. A tech check would be welcome, before pushing it live. -DePiep (talk) 05:18, 12 April 2022 (UTC)
Lua Pattern matching help
From the following module call, {{#invoke:WikidataIB|getValue|qid=Q60165516|P131|qual=DATES|fwd=ALL|osd=no|noicon=yes|linked=false}}
Prakasam district (1970–2022), Guntur district (–1970), Bapatla district (2022–)
I would like to extract as given below.
Bapatla district (2022–) Prakasam district (1970–2022),
In general the following matches are required.
1)start has a value, with end value of 2022
2)a start value of 2022 and no end value
3)start has no value, but end value of 2022
3)Start has no value and end has no value
I can get these cases individually as shown below.
case 1
{{#invoke:String|match|{{#invoke:WikidataIB|getValue|qid=Q60165516|P131|qual=DATES|fwd=ALL|osd=no|noicon=yes|linked=false }}|(%S+ district %(.-2022%))|plain=false}}
Prakasam district (1970–2022)
case 2
- with a different qid
{{#invoke:String|match|{{#invoke:WikidataIB|getValue|qid=Q60165583|P131|qual=DATES|fwd=ALL|osd=no|noicon=yes|linked=false }}|(%S+ district %(2022.-%))|plain=false}}
Bapatla district (2022–)
Case 3
{{#invoke:String|match|{{#invoke:WikidataIB|getValue|qid=Q60165583|P131|qual=DATES|fwd=ALL|osd=no|noicon=yes|linked=false }}|(%S+ district %(.-2022%))|plain=false}}
Prakasam district (–2022)
Case 4
- with a different qid
{{#invoke:String|match|{{#invoke:WikidataIB|getValue|qid=Q11104042|P131|qual=DATES|fwd=ALL|osd=no|noicon=yes|linked=false }}|(%S+ district)|plain=false}}
Prakasam district
Can you help by giving simple mediawiki template calls to WikidataIB or a complete script to get these values with links and a comma separator, even if the district name has upto three words separate by space? Arjunaraoc (talk) 06:09, 16 April 2022 (UTC)
- After some research I found {{wikidata}} to be a more powerful way to access data from wikidata and used the current parameter to get currently valid data item. Arjunaraoc (talk) 10:32, 2 May 2022 (UTC)
Error output on a module that should otherwise work
On my creative-venture wiki on Miraheze, I've recently set up a module called "Find", based on the "find" function at WP's Module:String. Minutes ago, I test-ran it through Special:ExpandTemplates with this sample code (and a couple of variants thereof):
{{#invoke:Find|find|This is a test.|test}}
On WP itself, this should give out "11" as the result. So far, however, these tests over on Miraheze output the error message "Lua error in Module:Find at line 35: attempt to call field '_getParameters' (a nil value)." (Although "_getParameters" isn't referenced anywhere else in this case.)
Sorry, only pinging here because 1) I'm pretty much inexperienced with Scribunto/Lua (being used so much to the old-school style of things with ParserFunctions) and 2) a bit of urgent help is needed. Can someone more qualified troubleshoot this module code and tell me what I missed?
--[[
find
This function allows one to search for a target string or pattern within another
string.
Usage:
{{#invoke:String|find|source_str|target_string|start_index|plain_flag}}
OR
{{#invoke:String|find|source=source_str|target=target_str|start=start_index|plain=plain_flag}}
Parameters
source: The string to search
target: The string or pattern to find within source
start: The index within the source string to start the search, defaults to 1
plain: Boolean flag indicating that target should be understood as plain
text and not as a Lua style regular expression, defaults to true
If invoked using named parameters, Mediawiki will automatically remove any leading or
trailing whitespace from the parameter. In some circumstances this is desirable, in
other cases one may want to preserve the whitespace.
This function returns the first index >= "start" where "target" can be found
within "source". Indices are 1-based. If "target" is not found, then this
function returns 0. If either "source" or "target" are missing / empty, this
function also returns 0.
This function should be safe for UTF-8 strings.
]]
--[[From w:Module:String#L-324]]
--[[This is a partial stand-in for the {{#rmatch:}} function offered by mwe:RegexFunctions, currently disabled on Miraheze per phab:T8866]]
local str = {}
function str.find( frame )
local new_args = str._getParameters( frame.args, {'source', 'target', 'start', 'plain' } )
local source_str = new_args['source'] or ''
local pattern = new_args['target'] or ''
local start_pos = tonumber(new_args['start']) or 1
local plain = new_args['plain'] or true
if source_str == '' or pattern == '' then
return 0
end
plain = str._getBoolean( plain )
local start = mw.ustring.find( source_str, pattern, start_pos, plain )
if start == nil then
start = 0
end
return start
end
return str
--Slgrandson (How's my egg-throwing coleslaw?) 12:23, 17 April 2022 (UTC)
str._getParameters()
must be defined in you module somewhere or you will get that error. At Module:String, that function is defined at line 524 et seq. Copy that into you module and see if that fixes your problem.- —Trappist the monk (talk) 12:30, 17 April 2022 (UTC)
- Along with "_getBoolean"--which managed to do the trick. Thanks a dozen! --Slgrandson (How's my egg-throwing coleslaw?) 12:57, 17 April 2022 (UTC)
How do i find specific Module pages?
I was wondering if there was a way to find the module page to templates if they dont link to them directly? i wanted to improve Plantilla:Ficha de comida (spanish wiki) by translating some of the english (Template:Infobox food) but i cant seem to find the module page for it.Kaidros (talk) 04:58, 20 April 2022 (UTC)
- One useful method is to preview an edit to a page where you replace the contents with a very simple example of using the template. At the bottom, you can view templates used on the previewed page. That includes what modules were called. It's probably es:Module:Ficha. Johnuniq (talk) 05:27, 20 April 2022 (UTC)
How to use a string read as tablename?
I have read a variable as string, say 'tFoo'
. Now I want that name to be used as a table id: table.insert( 'tFoo', 'someValue1' )
. This produces an error (like "error input variable 1: table expected, got string"). How can I use that string as table-name in there? (note: the table name is known beforehand, from a limited list of five, so is declared as local tFoo = {}
).
In code, essense lines:
local someFunction()
local tFoo = {}
local sInput
sInput = 'tFoo'
table.insert( 'tFoo', 'someValue1' ) -- triggers error
return table.concat( 'tFoo', ";" )
end
DePiep (talk) 06:20, 22 April 2022 (UTC)
local function someFunction() local tFoo = {} local sInput sInput = 'tFoo' table.insert( tFoo, 'someValue1' ) return table.concat( tFoo, ";" ) end
- Johnuniq (talk) 07:23, 22 April 2022 (UTC)
- Hmm, I just read this again. Are you saying you want the name of the table to be determined when the program runs? You can't do that in Scribunto's Lua. You would need to have a series of if...elseif...end tests to work out which table to use. If you describe the problem a bit more I can provide an example. Johnuniq (talk) 07:26, 22 April 2022 (UTC)
- Actually, line 5 should be using the input / replies unchanged OK
- Hmm, I just read this again. Are you saying you want the name of the table to be determined when the program runs? You can't do that in Scribunto's Lua. You would need to have a series of if...elseif...end tests to work out which table to use. If you describe the problem a bit more I can provide an example. Johnuniq (talk) 07:26, 22 April 2022 (UTC)
table.insert( sInput, 'someValue1' ) -- triggers error
As Johnuniq said, but to avoid if...elseif...end tests use a table of all five tables like in
function p.test()
local tfoo1 = {1,2,3}
local tfoo2 = {4,5,6}
local all_tables = {}
all_tables["tFoo1"] = tfoo1
all_tables["tFoo2"] = tfoo2
local sInput = 'tFoo2'
local operate_on = all_tables[sInput] or {}
table.insert(operate_on , 'someValue1' )
return table.concat(operate_on, "; " )
end
This returns "4; 5; 6; someValue1". I introduced "operate_on" for the case your sInput does not match any of the tables, but you probably do not need it. Ponor (talk) 08:41, 22 April 2022 (UTC)
if i understood the question (and the documentation) correctly, this can be achieved with _G['tFoo'], so the first example should work like so:
local someFunction()
tFoo = {} -- _G[something] only works for globals
local sInput
sInput = 'tFoo'
-- should work, i did not try: _G[sInput] is the global variable tFoo.
table.insert( _G[sInput], 'someValue1' )
return table.concat( _G[sInput], ";" )
end
in general it is not a good practice to use globals. if you want a string-indexed table of tables, per the example above, i will only suggest to construct it in a more concise way than the example: one-time variables like the inside tables in the example are just noise. i think it's more readable and maintainable, like so:
function p.test()
local all_tables = { -- if this is required in multiple places, make it module local rather than function local.
["1st table name"] = {1,2,3},
["2nd table name"] = {4,5,6},
}
-- ....
peace - קיפודנחש (aka kipod) (talk) 02:37, 23 April 2022 (UTC)
- Using _G is interesting but it is simply a particular case of Ponor's example where _G is used instead of all_tables. Johnuniq (talk) 03:31, 23 April 2022 (UTC)
Recap
- Recap; confusion/mistakes fixed:
- Original post by DePiep: I have read a variable as string, say
'tFoo'
. Now I want that name to be used as a table id:table.insert( 'tFoo', 'someValue1' )
. This produces an error (like "error input variable 1: table expected, got string"). How can I use that string as table-name in there? (note: the table name is known beforehand, from a limited list of five, so is declared aslocal tFoo = {}
).local function someFunction() local tFoo = {} local sInput sInput = 'tFoo' table.insert( sInput, 'someValue1' ) return table.concat( sInput, "; " ) end
- Note by Johnuniq:
read the name of the table to be determined when the program runs? You can't do that in Scribunto's Lua
. - Workaround by Ponor (shortened here):
function p.test()
local tfoo1 = {1,2,3}
local tfoo2 = {4,5,6}
local all_tables = {}
all_tables["tFoo1"] = tfoo1
all_tables["tFoo2"] = tfoo2
local sInput = 'tFoo2'
table.insert( all_tables[sInput] , 'someValue1' )
return table.concat( all_tables[sInput] , "; " )
end
Lua object coding (like mw.html)
I'd like to start programming by object, like building mw.html. Can anyone mention some live modules with good, basic examples? (And more complicated ones maybe). -DePiep (talk) 11:16, 8 May 2022 (UTC)
Code for regex support
As I type, I'm planning to add real regex support for my creative-venture wiki's "Find" module, an example being:
{{#invoke:Find|regex|test|^[rstlne]}}
→ 1
How does one deal with the final part Lua-wise? (Again, keep in mind I have little experience with Scribunto/Lua.) --Slgrandson (How's my egg-throwing coleslaw?) 13:54, 13 May 2022 (UTC)
- Lua does not do regex. Lua does patterns. There is a lot of similarity but common regex stuff like
|
is not supported. You might look at Module:String for finding something in a string using lua patterns. - —Trappist the monk (talk) 14:04, 13 May 2022 (UTC)
- iiuc, they are talking about their own wiki.
- @Slgrandson: i think you should ask this on mw: - there must be a way to add a library to scribuntu. personally, i would look for the sources of the "ustring" library, which adds unicode support to scribuntu, and follow their example (TBH, i did not verify, but i assume this lib is written in C).
- you may want to expand this lib instead of creating a new one, e.g. add mw.ustring.regex() function(s) (once you add "true" regex, you may be tempted to add "rmatch(), rgsub() etc.), and have your module simply pipe this functionality so it's usable by templates.
- you may also look at doing it purely in lua - i imagine this will be very inefficient, but maybe you don't care about performance - see e.g https://gist.github.com/luiseduardohd/10668729
- as a side, "real regex" is not as cut and dried as one might imagine, and some tools and libraries discriminate between, e.g., "perl regex", "pure regex", and whatnot. i remember JS regex was missing some features for a long time, specifically "negative lookbehind", which gave the few who really needed it no end of pain - this one was rectified a while ago).
- peace. קיפודנחש (aka kipod) (talk) 16:12, 13 May 2022 (UTC)
- Incidentally: in my regex, the parameters
test
and^[rstlne]
return "t" not "1" -- as I expected. - My thoughts: the requested Lua Module:regex could translate (=string change) Regex-code into pattern-code, by replacing regex escape "\" with pattern escaper "%" (first and foremost). Also it c/should check for unsupported code, (eg, "|" for or cannot be patternalised) and return an error. -DePiep (talk) 18:10, 13 May 2022 (UTC)
- Incidentally: in my regex, the parameters
- The question needs clarification regarding what "real regex" means. If something like Perl compatible regex is envisaged, forget it—it's not going to happen. If content with Lua's regex, see Module:String. Regarding Scribunto's ustring library, it is entirely written in Lua, including regex handling—an amazing accomplishment. Johnuniq (talk) 23:39, 13 May 2022 (UTC)
- Source code: https://github.com/wikimedia/mediawiki-extensions-Scribunto/tree/master/includes/engines/LuaCommon/lualib/ustring. Although, on actual Wikipedia, the PHP version of Ustring (source code: https://github.com/wikimedia/mediawiki-extensions-Scribunto/blob/8b707a45a540ebdc7348a97904ffd65ad7bd02ad/includes/engines/LuaCommon/UstringLibrary.php) for performance reasons. Nor is real regex
hopeless
as Johnuniq describes it, given the pure-Lua implementation that Kipod linked above. Way back in 2016, a since-banned user said thatnamely that someone will write Module:RegEx
as an argument that the developers denying modules programmers a real regex library was counterproductive; <sarcasm>perhaps it's time to validate that hypothetical and repeat the circumstances that lead to the installation of Scribunto in the first place</sarcasm>. * Pppery * it has begun... 00:14, 14 May 2022 (UTC)
- Source code: https://github.com/wikimedia/mediawiki-extensions-Scribunto/tree/master/includes/engines/LuaCommon/lualib/ustring. Although, on actual Wikipedia, the PHP version of Ustring (source code: https://github.com/wikimedia/mediawiki-extensions-Scribunto/blob/8b707a45a540ebdc7348a97904ffd65ad7bd02ad/includes/engines/LuaCommon/UstringLibrary.php) for performance reasons. Nor is real regex
My point was that it should be pretty straightforward for a non-wikimedia wiki to add "true" regex support. I stand corrected regarding ustring implementation, but this only makes it even easier: use the php implementation, and figure out how to hook one or few more functions, which can be implemented as a shim piping inbuilt php regex. For wikimedia wikis, we should limit ourselves to lua pattern matching, and jot this down as "regex envy" which won't be satisfied. Peace - קיפודנחש (aka kipod) (talk) 14:52, 14 May 2022 (UTC)
Changing flag icon formats from .svg.png and .png to .svg
Is there anyway to change formats of flag icons from .png and .svg.png to .svg if possible? Any specific code or module? Let me know. FireDragonValo (talk) 19:12, 13 May 2022 (UTC)
- @FireDragonValo: What are you trying to fix? A file cannot be simply converted between formats using Lua modules. NguoiDungKhongDinhDanh 20:12, 13 May 2022 (UTC)