Wikipedia talk:Lua/Archive 5

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

Lua conversion for Template:Sensitive IP addresses, and is a Lua-to-JSON feature possible?

Following up on

Module:Sensitive IP addresses containing the Lua code proper and Module:Sensitive IP addresses/List of addresses containing the list of IPs and associated owners.Jo-Jo Eumerus (talk, contributions
) 21:44, 12 July 2016 (UTC)

Yes, it's possible. I did something similar with Lua data for Module:Signpost, its data tables at Module:Signpost/index/2016 etc., and User:Mr. Stradivarius/gadgets/SignpostTagger.js. I've actually started working on this, but I decided to go about it in a slightly roundabout way - I've started writing a library for dealing with IP addresses at Module:IP, and I plan to convert Template:Sensitive IP addresses after that's done. — Mr. Stradivarius ♪ talk ♪ 23:23, 12 July 2016 (UTC)
Sweet. Mr. Stradivarius, take note that I've proposed to use Template:Sensitive IP addresses on MediaWiki talk:Blockiptext and Wikipedia:Blocking policy, so some alterations may happen.Jo-Jo Eumerus (talk, contributions) 23:29, 12 July 2016 (UTC)
Module:IPblock does a lot of work with IPv4 and IPv6 addresses. It can parse them from wikitext and put each address in a table (same structure for both v4 and v6). Addresses can be compared, sorted, and masked, and the number of common prefix bits can be calculated (function common_length is astonishing!). It can output the text representation of an IP. Johnuniq (talk) 23:50, 12 July 2016 (UTC)
That's an impressive module! Thanks for pointing it out - I wasn't aware of it before. My instinct would be to move the generic IP functions to
Module:Sensitive IP addresses. What do you think? And also, what do you think of the interface I have sketched out? That is still a work in progress, and we can change stuff as necessary. — Mr. Stradivarius ♪ talk ♪
02:01, 13 July 2016 (UTC)
Moving the code is fine. I'd like to postpone thoughts from me for 24 to 48 hours. If you're in a hurry, go for it; otherwise, you might wait for me to copy in the functions I think would help so they can be massaged into the required form. I do not understand what SignpostTagger.js or the module are doing, but it looks like the js is writing the module code—amazing! By the way, if you've never tried it, it can be quite easy and efficient for a module to parse a long string. That might be a good technique for the current IP application where all that is wanted is a plain-text list of IP addresses, possibly with CIDR ranges, and that would be simple to parse although my module does not handle big CIDR ranges because of some internal calculations it does (it keeps a list of every IP in a range, and that's not feasible for IPv6 or big IPv4 ranges). For an example of parsing a long string, see the "list" parameter in Template:Football manager history#Examples. The code which parses that is function make_list in Module:Football manager history. Johnuniq (talk) 04:50, 13 July 2016 (UTC)

@Mr. Stradivarius: I put some preliminary thoughts at Module talk:IP. Johnuniq (talk) 11:10, 14 July 2016 (UTC)

Adding references to Infobox template

I would like to be able to add references to lua template and have them show up at the bottom of the wikipedia page as when the <ref> tag is used. Is there a lua module somewhere to help me do this? https://en.wikipedia.org/wiki/User:Julialturner/RELN see the section with diseases. These numbered references items should correspond to those numbered in the reference section. Thanks you. Julialturner (talk) 05:53, 13 July 2016 (UTC)

The only way to get a reference is for the wikitext to include <ref> tags. I don't think Module:Sandbox/genewiki/alllua outputs any refs. Modules are run after several other steps in preparing the wikitext are completed, and one of those steps involves processing ref tags. I think that means that any ref tags output by a module won't work. Instead, it appears a module would need to use extensionTag. I have never tried that. By the way, Lua handles true/false variables. Instead of f = "true" (a string), use f = true. After doing that, f can be tested with if f then ... (no need to mention true). Johnuniq (talk) 06:14, 13 July 2016 (UTC)
Thank you for the extensionTag suggestion I will try to go that route and also for the true false pointer. Julialturner (talk) 19:16, 13 July 2016 (UTC)
if you need to process stuff that is typically processed before the module is invoked, use frame:callParserFunction(), frame:extensionTag(), or frame:expandTemplate() (the last one only works if you have a template that produces the tag, which is often the case with ref tags) . it's explained here, and interestingly enough, the documentor(s) (sp?) chose the "ref" tag for one of the examples. peace - קיפודנחש (aka kipod) (talk) 22:49, 13 July 2016 (UTC)
I think you made a typo there - that should be frame:expandTemplate, not frame:extendTemplate. — Mr. Stradivarius ♪ talk ♪ 23:17, 13 July 2016 (UTC)
thanks. fixed. whoever reads this should not go by what i wrote directly - the important part was the link to the section on the manual page. peace - קיפודנחש (aka kipod) (talk) 14:03, 14 July 2016 (UTC)

Hey.

I was hoping for someone to create a new function to the Module:String.

The function will give the first line of a string

for example:

hello

world

what's

up

will give you hello Thanks in advance--Mikey641 (talk) 15:51, 22 July 2016 (UTC)

  • This is not necessary:
    {{#invoke:String|match|hello
    
    world
    
    what's
    
    up
    |^%s*.-
    
    |||}}
    hello

Paweł Ziemian (talk) 18:46, 22 July 2016 (UTC)

Paweł Ziemian Thanks alot!!!--Mikey641 (talk) 00:25, 24 July 2016 (UTC)

Saving modules

I am having difficulty saving a module and its documentation page. Is there anyone I can ask for help? --פוילישער (talk) 18:29, 26 July 2016 (UTC)

@פוילישער: What happens when you try to save it? Could you give us a link to the pages you are trying to save, or maybe paste the content here if that's easier? — Mr. Stradivarius ♪ talk ♪ 22:46, 26 July 2016 (UTC)
Thank you. The problem manifests itself on yiwiki. I was trying to save the code for Module:Infobox. You can find it in my sandbox (as part1). When I try to save it nothing happens.


Many thanks --פוילישער (talk) 05:41, 27 July 2016 (UTC)
I have just tried again without the modifications I made and have been successful this time. I must have introduced some error in the code. --פוילישער (talk) 05:55, 27 July 2016 (UTC)

Is frame:getParent() efficient?

There seem to be two ways for a module to get the parameters from the template that invoked it: one is to have the template explicitly pass all of its parameters, and the other is to have the module get all the parameters via frame:getParent().args. Does anyone know if one way is computationally cheaper that the other? Uanfala (talk) 13:13, 5 August 2016 (UTC)

I do not know the implementation details, however I suspect that frame:getParent().args is better. The parameters passed to template are already parsed but using them while invoking the template need additional cost. But forget the details and try Module:Arguments, which make all the dirty things transparent and allows to mix various method including calling functions even from other modules. Paweł Ziemian (talk) 15:35, 5 August 2016 (UTC)
The two ways to get parameters into a module are:
  1. frame.args parameters from the template invoking the module
  2. frame:getParent().args parameters from the page using the template
You probably mean that wikitext in the template could attempt to pass the expected parameters so #2 would be a duplicate of #1. There is no reason to do that and modules are sufficiently fast to know that the overhead of getParent is trivial. Like Paweł Ziemian, I would expect that duplicating the parameters in the template would be a tiny bit slower because it would require MediaWiki to parse the parameters twice, whereas the getParent code is probably much more efficient. Module:Arguments combines the parameters from the above two methods. Johnuniq (talk) 01:16, 6 August 2016 (UTC)
When Scribunto was first being developed, the ability to get arguments directly from frame:getParent().args was actually one of the big reasons that Lua modules were anticipated to be faster than wikitext templates. This is apparent from the design documents, which talk about a "substantial cost" for "every triple brace and every pipe". The speed of parsing wikitext improved greatly with the introduction of HHVM in 2014 (a year after the Scribunto rollout), but I am guessing that you could still get a considerable performance boost by switching from frame.args to frame:getParent().args for modules that accept a lot of parameters. To say anything for certain someone would need to run some benchmarks, though. — Mr. Stradivarius ♪ talk ♪ 05:30, 6 August 2016 (UTC)
More importantly, I can't imagine there being any downside to using frame:getParent().args over frame.args, so you may as well use it. These days I mostly use Module:Arguments with the wrappers option, though, which has the same benefits as using frame:getParent().args and also allows you to use the same arguments with #invoke directly if you want. Module:Arguments also allows you to automatically trim whitespace and to remove blank arguments, which I find is almost always needed. — Mr. Stradivarius ♪ talk ♪ 05:38, 6 August 2016 (UTC)
Thank you everyone for the responses. I'll have a look at Module:Arguments (hopefully this isn't going to slow things down compared to frame.getParent().args?). Speaking of performance, I notice that for a few days now I haven't been able to see much in the Parser profiling data area at the bottom of the page when previewing an edit. This used to be a table containing information about Lua memory usage or template argument size, but now it only lists the number of Wikibase entities. Does anyone know anything about that? Uanfala (talk) 15:44, 10 August 2016 (UTC)

Passing wikitables as arguments

Hello, it seems that passing Wikitables as arguments does not always work as expected. The internal "|" are apparently interpreted as parameter separators: see Commons:Module talk:Artwork. Does anyone have a solution, other than rewriting all templates to avoid Wikitables ? --Zolo (talk) 06:17, 12 August 2016 (UTC)

if you must pass a whole wikitable, have you tried frame:preprocess?
Trappist the monk (talk) 09:16, 12 August 2016 (UTC)
nevermind; wrong end of the process. It's not clear to me what it is that you are trying to accomplish with the module that isn't already accomplished by the template. You can, of course replace the content of the template with a module that writes the html of a table (HTML library). But why do that if the template does what it is supposed to do?
Trappist the monk (talk) 09:29, 12 August 2016 (UTC)
this issue is not specific to lua - it is a general thing with passing tables as parameters to templates. basically, there are 2 ways to handle this: (1) replace the | and || with {{!}} and {{!!}}, or (2) use html tags for the tables instead of wikicode (i.e., <table>..</table>, <tr>..</tr>, <th>..</th>, and <td>..</td>). HTH, peace - קיפודנחש (aka kipod) (talk) 15:49, 12 August 2016 (UTC)
Mediawiki parses the "|" character expecting a new parameter after it. To escape it, you have to use nested templates to escape this character. This was mentioned above by קיפודנחש (aka kipod) -- Don't forget that the same goes for the "=" character as well. -- Matroc (talk) 19:19, 12 August 2016 (UTC)
Thanks for the replies. If I undestand right, you are saying that I should change the Wikitext passed by the parameters to make it work ? What I don't get is why the non-Lua version works fine but not the Lua-based sandbox, in cases like {{Artwork|permission = {{PD-art}} }}.
@Trappist the monk: the template works, but is really not suited for integrating somewhat complex Wikidata retrieving features that would be really useful for internationalized artwork descriptions on Commons. --Zolo (talk) 21:31, 12 August 2016 (UTC)
The module needs to get a wikitable as an argument only because a table is the only kind of output produced by the permissions template, right? Wouldn't it make sense then to change the permissions template so that it can optionally produce its output in another, more parseable, format? Disclaimer: I don't know much about either Lua or templates Uanfala (talk) 21:53, 12 August 2016 (UTC)

ColPollTable

Not sure where else to put this. I turned Template:ColPollTable into a module (small test here). But it's weird because this is set to replace 20 independent templates. What bugs me though is whether or not the template is necessary. It seems to be used on only a few pages, which makes me wonder if its functionality might be covered by a superior template. If that's not the case and the template serves a unique function, then I'm not sure exactly how I should proceed to update the templates and their calls. moluɐɯ 13:35, 30 August 2016 (UTC)

If you check WhatLinksHere with normal links hidden, you'll see that the template doesn't even have a single transclusion. It should probably be nominated at
TfD as unused, not converted to Lua. There's no problem with converting it if you plan to actually use it, of course, but I can see why it's not been adopted anywhere - even on my huge 1920px monitor it still scrolls horizontally. That can't be fun if you're using a mobile device. — Mr. Stradivarius ♪ talk ♪
14:30, 30 August 2016 (UTC)
The main template isn't used anywhere, but its various subtemplates are. moluɐɯ 15:38, 30 August 2016 (UTC)
The link provided by Mr.S. shows that Template:ColPollTable is not transcluded anywhere—it is not used. I have not looked at what's going on, but the subtemplates must not be calling it. Are you saying that your new code could be used to replace the subtemplates, despite {{ColPolTable}} being currently unused? Johnuniq (talk) 00:45, 31 August 2016 (UTC)
Yes. I guess I should clarify what's going on then. This seems to be an old and rather unsophisticated template. The base template, ColPollTable, provides 20 columns for weeks, invariably. To use a number of weeks less than 20, 19 other templates exist—ColPollTable/1–ColPollTable/19. I took this idea and merged it into a single module. Instead of explicitly defining how many weeks to display, the module looks for the highest week number defined, and works from there, eliminating the need for each of these subtemplates. moluɐɯ 11:17, 31 August 2016 (UTC)
Ah, that makes more sense. I see that
Template:ColPollTable/20 is transcluded 12 times, for example. I also see that there are subtemplates that number higher than 20. For now I think it would be fine to just update the transclusions to use the new module; we can worry about how to make things look nice on mobile later. However, before that, it might be a good idea to ask at the relevant WikiProjects as to whether they have a better/more standard way of doing things. — Mr. Stradivarius ♪ talk ♪
01:48, 1 September 2016 (UTC)
Alright thanks. I'll do that. moluɐɯ 10:53, 1 September 2016 (UTC)

Different options

In Module:Routemap/sandbox, I'd like to use the option removeBlanks = false for the p._BSrow function, but only that function. Is it necessary to make another module for this? Jc86035 (talk • contribs) Use {{re|Jc86035}} to reply to me 12:25, 1 September 2016 (UTC)

I think you are saying that wikitext calling a template might include |removeBlanks=false to not remove blanks, or might omit that parameter to include them. And the template would invoke function BSrow in the module. I don't see a problem and don't see why another module might be needed. What is the concern?
My instinct is telling me there is a problem with the positive(x) and negative(x) functions that would presumably be used to test args.removeBlanks. If the wikitext omits the parameter (or equivalently, given that Module:Arguments is used probably with defaults, omits the value), positive(args.removeBlanks) would evaluate as false, and so would negative(args.removeBlanks). That's a bit awkward. Johnuniq (talk) 00:20, 2 September 2016 (UTC)
@Johnuniq: I meant as in the Module:Arguments option, not adding it from the frame or whatever. (The positive(x) and negative(x) functions are purely for internal use and I'm not sure why I'd use an args.removeBlanks in them.) Would having a makeInvokeFunction2 (duplicate but using removeBlanks = false) work, or is there a better solution? Jc86035 (talk • contribs) Use {{re|Jc86035}} to reply to me 07:08, 2 September 2016 (UTC)
@Jc86035: Oops, you can tell I haven't used Module:Arguments! No wonder I didn't understand what the concern was. Have a look at my diff to the sandbox which I think will do the job. You don't need another module, and if what I did doesn't work, it can be fixed. You might test it with a few lines of test code that returns dummy text depending on the arguments so you can see if it does what is expected. Johnuniq (talk) 07:44, 2 September 2016 (UTC)
@Johnuniq: Seems to be working ({{User:Jc86035/sandbox3|||*3|||O5=utSTRq|bg=}} returns \\*3\\!~utSTRq~~ ~~ ~~ ~~ ~~bg=); thanks! Jc86035 (talk • contribs) Use {{re|Jc86035}} to reply to me 07:49, 2 September 2016 (UTC)

The Wikidata implementation in {{Coord}} (activated when |1= and |2= are both missing) doesn't seem to be working. On, for example, Empire State Building, {{Coord}} returns "40.7483°N 73.9853°WInvalid arguments have been passed to the {{#coordinates:}} function". Coordinates seem to be fine (other than that the coordinates were originally imported to Wikidata with 11000th of an arcsecond's accuracy), but it still returns the error. Does anyone have any idea why? Thanks, Jc86035 (talk) Use {{re|Jc86035}}
to reply to me
13:22, 7 September 2016 (UTC)

I have only glanced at Template:Coord but doesn't it invoke the module and {{#coordinates:...}}? I don't understand what the bits and pieces are supposed to do, but it looks like #coordinates will output that error message unless it is fed valid data, and putting "{{Coord}}" on a page would not feed it anything valid that I can see. Johnuniq (talk) 02:26, 8 September 2016 (UTC)
In fact, previewing "{{#invoke:Coordinates|coord}}" at the article displays what is wanted without an error. Johnuniq (talk) 02:28, 8 September 2016 (UTC)
{{#property:P625|from=Q9188}} - 40°44'54"N, 73°59'7"W if you just want standalone coordinates (with no links). -- Matroc (talk) 03:15, 8 September 2016 (UTC)
@Johnuniq and Matroc: Oh, I see. Thanks. (Would it be possible for the {{#coordinates:}} part to be put into the module as well, since otherwise the Wikidata implementation is a bit broken? There's Module:WikidataCoord, but it doesn't have a template wrapper and is only used on a few pages.) Jc86035 (talk) Use {{re|Jc86035}}
to reply to me
05:10, 8 September 2016 (UTC)
I remember that there was a problem with some kind of incompatibility between #coordinates and #invoke when the module was first written, which is why it's not already included. I'm not sure if that still applies. — Mr. Stradivarius ♪ talk ♪ 05:30, 8 September 2016 (UTC)
@Mr. Stradivarius: Could this be solved by making a subtemplate containing just {{#coordinates:}} (and using it through the module), or is there a better solution? Jc86035 (talk) Use {{re|Jc86035}}
to reply to me
07:06, 8 September 2016 (UTC)
Yes, back in the early days there wasn't a good way to use #coordinates within Lua. I think "frame:callParserFunction" makes this possible now, though I haven't tried it. Dragons flight (talk) 07:26, 8 September 2016 (UTC)
@Dragons flight: Tried it; returns an error: Lua error in Module:Coordinates/sandbox at line 592: attempt to index local 'frame' (a nil value). Maybe it's because everything goes through Module:Arguments? A similar setup works for Module:Geobox coor though. Jc86035 (talk) Use {{re|Jc86035}}
to reply to me
10:18, 8 September 2016 (UTC)
		-- https://bugzilla.wikimedia.org/show_bug.cgi?id=50863 RESOLVED
		return mw.getCurrentFrame():callParserFunction("#coordinates", params) or ""

where params is a table with parameters as described in mw:Extension:GeoData. Paweł Ziemian (talk) 20:30, 8 September 2016 (UTC)

Also, a bit off-topic; with Kartographer extension (if installed) you can create a link to a map (using decimal coordinates found in Wikidata): <maplink zoom="13" longitude="-73.985656" latitude="40.748433" /> 40°44′54″N 73°59′8″W or <maplink zoom="13" text="Click Me!" longitude="-73.985656" latitude="40.748433" /> Click Me! - The decimal coordinates can be found by querying Wikidata. -- It all depends on what you are trying to do and what can be done with available tools/templates/modules etc.
Check out Solomon R. Guggenheim Museum Best wishes!-- Matroc (talk) 02:26, 9 September 2016 (UTC)
@
Help:Coordinates in infoboxes (i.e. converting the newly-deprecated |latd=, |latm=, |longd= etc. parameters in several hundred thousand infoboxes to just |coordinates=) and this could have quite some changes in how the replacement's being carried out. (Side note: what do the Geohack parameters in {{#coordinates:}} actually do?) Jc86035 (talk) Use {{re
|Jc86035}}
to reply to me
05:12, 9 September 2016 (UTC)
Pinging JJMC89 and Jonesey95. Jc86035 (talk) Use {{re|Jc86035}}
to reply to me
05:13, 9 September 2016 (UTC)
Thanks for the ping, but this is over my head. I can code templates, but Lua and wikidata calls are out of reach for me. – Jonesey95 (talk) 05:40, 9 September 2016 (UTC)
That was just a quick demo of getting the coordinates for creating a map using maplink or mapframe as I use in enWikivoyage... I think I marked that as off-topic earlier as I thought I was getting away from what you might be trying to accomplish. Different animals. I do search Wikidata for latitude and longitude (in decimal dms) form for use by maps and listings by using the Wikidata ID (Qnnn) and lookup up the coords property (P625) and look for the array value for longitude and latitude. It can be complex and confusing at times. I wish I could help you more. All the best! -- Matroc (talk) 06:39, 9 September 2016 (UTC)
@Johnuniq, Mr. Stradivarius, and Dragons flight: I've tried adding it to the sandbox; however, there seem to be some weird errors (see Module talk:Coordinates/testcases) which don't occur when I'm testing the template in WP:Sandbox (specifically with the testcase with missing minutes/seconds). Jc86035 (talk) Use {{re|Jc86035}}
to reply to me
08:37, 9 September 2016 (UTC)

trouble with Expansion depth

Commons is a project where we spend a lot of effort on presenting everything in the language of the person viewing the page. That was traditionally done by layers and layers of very large and complicated templates, some of which become so complicated as to become unmanageable. Over the last several years we were working on transitioning some of them to Lua, which is a great improvement. Recently me and others were working on transition of c:Template:Creator and c:template:Artwork to c:Module:Creator and c:Module:Artwork and we are running into a problem of Expansion depth. Template version of the templates do not trigger it, but Lua versions do. See for example c:Module talk:Creator/testcases. The issue seems to be that if a template written in Lua is processing output of another template written in Lua than that triggers Expansion depth error. I reported some earlier case in phabricator:T133918, it seems like it will be a blocking issue before c:Module:Creator can be used. Do anybody have experience with working with that limit or understands logic of how Lua triggers Expansion depth. --Jarekt (talk) 13:18, 17 September 2016 (UTC)

@Jarekt: In Module:Creator (in the p.creator function, line 262) you seem to be using both Args and args; is this intended? I'm not sure where the expansion depth error is in the page. Jc86035 (talk) Use {{re|Jc86035}}
to reply to me
13:37, 17 September 2016 (UTC)
Oh, I see the expansion depth error. Not sure about that; are there normally that number of creator templates on the same page? Might have something to do with it Jc86035 (talk) Use {{re|Jc86035}}
to reply to me
14:04, 17 September 2016 (UTC)
c:Module:Creator is still being written, but use of Args and args parameters was intentional as I am trying to switch to case non-sensitive parameters. Maybe I should use better variable names. Page User:Jarekt/a has a single Creator template with bunch of expansion depth errors. Same parameters passed to current {{Creator}} page are no problems. According to the documentation Expansion depthshould not depend on how many templates you have, but how many templates you have nested. At least that how it worked with templates. --Jarekt (talk) 16:22, 17 September 2016 (UTC)
@Jarekt: Whatever this is, it's a pretty fundamental problem: I can reproduce the expansion depth error by simply replacing the module content with
return {
	creator = function (frame)
		return frame.args.Workloc
	end
}
and by previewing Module talk:Creator/testcases using the "preview page with this template" feature. — Mr. Stradivarius ♪ talk ♪ 16:45, 17 September 2016 (UTC)
User:Mr. Stradivarius thank you for looking into it. I agree that it is quite fundamental. I had the same problem with using string templates (based on module:String) to process a string that come from another LUA based template. The issue seem to be with nesting of 2 lua based templates, no matter how simple. The troubling thing is that as more and more of our templates are converted to Lua, that will happen more often. The behavior does not seem to follow the documented rules of expansion depth error. --Jarekt (talk) 19:22, 17 September 2016 (UTC)
I did some debugging for you. The PHP stack trace looks, in part, like this repeated several times:
#8 PPTemplateFrame_Hash->getArguments() called at [/srv/mediawiki/php-1.28.0-wmf.18/extensions/Scribunto/engines/LuaCommon/LuaCommon.php:782]
#9 Scribunto_LuaEngine->preprocess(current, {{int:lang}}) called at [/srv/mediawiki/php-1.28.0-wmf.18/extensions/Scribunto/engines/LuaSandbox/Engine.php:407]
#10 Scribunto_LuaSandboxCallback->__call(preprocess, Array)
#11 LuaSandboxFunction->call(Object of class LuaSandboxFunction could not be converted to string, getLabel) called at [/srv/mediawiki/php-1.28.0-wmf.18/extensions/Scribunto/engines/LuaSandbox/Engine.php:319]
#12 Scribunto_LuaSandboxInterpreter->callFunction(Object of class LuaSandboxFunction could not be converted to string, Object of class LuaSandboxFunction could not be converted to string, getLabel) called at [/srv/mediawiki/php-1.28.0-wmf.18/extensions/Scribunto/engines/LuaCommon/LuaCommon.php:245]
#13 Scribunto_LuaEngine->executeModule(Object of class LuaSandboxFunction could not be converted to string, getLabel, tplframe{"entity":"<value><tplarg><title>1</title><part><name index=\"1\"/><value/></part></tplarg></value>", "lang":"<value><tplarg><title>2</title><part><name index=\"1\"/><value><template><title>int:lang</title></template></value></part></tplarg></value>", "link":"<value><tplarg><title>link</title><part><name index=\"1\"/><value>wikipedia</value></part></tplarg> </value>"}) called at [/srv/mediawiki/php-1.28.0-wmf.18/extensions/Scribunto/engines/LuaCommon/LuaCommon.php:898]
#14 Scribunto_LuaModule->invoke(getLabel, tplframe{"entity":"<value><tplarg><title>1</title><part><name index=\"1\"/><value/></part></tplarg></value>", "lang":"<value><tplarg><title>2</title><part><name index=\"1\"/><value><template><title>int:lang</title></template></value></part></tplarg></value>", "link":"<value><tplarg><title>link</title><part><name index=\"1\"/><value>wikipedia</value></part></tplarg> </value>"}) called at [/srv/mediawiki/php-1.28.0-wmf.18/extensions/Scribunto/common/Hooks.php:121]
#15 ScribuntoHooks::invokeHook(Object of class Parser could not be converted to string, tplframe{"1":"<value>Q47465</value>", "2":"<value><tplarg><title>1</title><part><name index=\"1\"/><value><template><title>int:lang</title></template></value></part></tplarg></value>", "link":"<value><template><title>#if:<tplarg><title>nolink</title><part><name index=\"1\"/><value/></part></tplarg></title><part><name index=\"1\"/><value>-</value></part><part><name index=\"2\"/><value>wikipedia</value></part></template></value>"}, Array) called at [/srv/mediawiki/php-1.28.0-wmf.18/includes/parser/Parser.php:3352]
#16 Parser->callParserFunction(tplframe{"1":"<value>Q47465</value>", "2":"<value><tplarg><title>1</title><part><name index=\"1\"/><value><template><title>int:lang</title></template></value></part></tplarg></value>", "link":"<value><template><title>#if:<tplarg><title>nolink</title><part><name index=\"1\"/><value/></part></tplarg></title><part><name index=\"1\"/><value>-</value></part><part><name index=\"2\"/><value>wikipedia</value></part></template></value>"}, invoke, Array) called at [/srv/mediawiki/php-1.28.0-wmf.18/includes/parser/Parser.php:3076]
#17 Parser->braceSubstitution(Array, tplframe{"1":"<value>Q47465</value>", "2":"<value><tplarg><title>1</title><part><name index=\"1\"/><value><template><title>int:lang</title></template></value></part></tplarg></value>", "link":"<value><template><title>#if:<tplarg><title>nolink</title><part><name index=\"1\"/><value/></part></tplarg></title><part><name index=\"1\"/><value>-</value></part><part><name index=\"2\"/><value>wikipedia</value></part></template></value>"}) called at [/srv/mediawiki/php-1.28.0-wmf.18/includes/parser/Preprocessor_Hash.php:1016]
#18 PPFrame_Hash->expand(<root><ignore><includeonly></ignore><template><title>#invoke: Wikidata </title><part><name index="1"/><value> getLabel </value></part><part><name>entity</name><equals>=</equals><value><tplarg><title>1</title><part><name index="1"/><value/></part></tplarg></value></part><part><name>lang</name><equals>=</equals><value><tplarg><title>2</title><part><name index="1"/><value><template><title>int:lang</title></template></value></part></tplarg></value></part><part><name>link</name><equals>=</equals><value><tplarg><title>link</title><part><name index="1"/><value>wikipedia</value></part></tplarg> </value></part></template><ignore></includeonly></ignore><ignore><noinclude> {{documentation}}</noinclude></ignore></root>) called at [/srv/mediawiki/php-1.28.0-wmf.18/includes/parser/Parser.php:3229]
#19 Parser->braceSubstitution(Array, tplframe{}) called at [/srv/mediawiki/php-1.28.0-wmf.18/includes/parser/Preprocessor_Hash.php:1016]
#20 PPFrame_Hash->expand(<root><template><title>Label</title><part><name index="1"/><value>Q47465</value></part><part><name index="2"/><value><tplarg><title>1</title><part><name index="1"/><value><template><title>int:lang</title></template></value></part></tplarg></value></part><part><name>link</name><equals>=</equals><value><template><title>#if:<tplarg><title>nolink</title><part><name index="1"/><value/></part></tplarg></title><part><name index="1"/><value>-</value></part><part><name index="2"/><value>wikipedia</value></part></template></value></part></template><ignore><noinclude> {{Documentation|Template:GeoName/doc}} [[Category:Multilingual tags: Locations in France|{{PAGENAME}}]] [[Category:Aix-en-Provence|~{{PAGENAME}}]] [[Category:Internationalization templates using LangSwitch|{{PAGENAME}}]] </noinclude></ignore></root>, 0) called at [/srv/mediawiki/php-1.28.0-wmf.18/includes/parser/Preprocessor_Hash.php:1449]
#21 PPTemplateFrame_Hash->cachedExpand(Template:Aix-en-Provence, <root><template><title>Label</title><part><name index="1"/><value>Q47465</value></part><part><name index="2"/><value><tplarg><title>1</title><part><name index="1"/><value><template><title>int:lang</title></template></value></part></tplarg></value></part><part><name>link</name><equals>=</equals><value><template><title>#if:<tplarg><title>nolink</title><part><name index="1"/><value/></part></tplarg></title><part><name index="1"/><value>-</value></part><part><name index="2"/><value>wikipedia</value></part></template></value></part></template><ignore><noinclude> {{Documentation|Template:GeoName/doc}} [[Category:Multilingual tags: Locations in France|{{PAGENAME}}]] [[Category:Aix-en-Provence|~{{PAGENAME}}]] [[Category:Internationalization templates using LangSwitch|{{PAGENAME}}]] </noinclude></ignore></root>) called at [/srv/mediawiki/php-1.28.0-wmf.18/includes/parser/Parser.php:3226]
#22 Parser->braceSubstitution(Array, frame{}) called at [/srv/mediawiki/php-1.28.0-wmf.18/includes/parser/Preprocessor_Hash.php:1016]
#23 PPFrame_Hash->expand(<value> <template><title>Aix-en-Provence</title></template>, <template><title>Paris</title></template>, <template><title>city</title><part><name index="1"/><value>Auvers-sur-Oise</value></part></template>, <template><title>Marseille</title></template> </value>, 4) called at [/srv/mediawiki/php-1.28.0-wmf.18/includes/parser/Preprocessor_Hash.php:1529]
#24 PPTemplateFrame_Hash->getNamedArgument(Workloc) called at [/srv/mediawiki/php-1.28.0-wmf.18/includes/parser/Preprocessor_Hash.php:1541]
#25 PPTemplateFrame_Hash->getArgument(Workloc) called at [/srv/mediawiki/php-1.28.0-wmf.18/includes/parser/Preprocessor_Hash.php:1473]
What seems to be happening there is that MediaWiki attempts to expand the Workloc parameter (#25-23), which expands {{Label}} (#22-18), which invokes c:Module:Wikidata (#17-11), which calls frame:preprocess('{{int:lang}}') in some manner (#10-9), which needs to expand the parameters passed into the current frame (#8), which includes Workloc so repeat until the expansion depth is exceeded. The top-level local defaultlang = mw.getCurrentFrame():preprocess("{{int:lang}}") in c:Module:Wikidata, c:Module:Wikidata/Tools, c:Module:Wikidata/FormatEntity, and so on looks particularly suspicious. BJorsch (WMF) (talk) 23:54, 17 September 2016 (UTC)
BJorsch (WMF) thanks I will study this chain. I think I get it. frame:preprocess('{{int:lang}}') is actually usually written as mw.message.new( "lang" ):plain() to avoid calling preprocess. It returns users preferred language and there was a discussion lattely here how it no longer works. @Zolo: as the author of c:Module:Wikidata maybe you can look at this as well. We should not need to call frame:preprocess('{{int:lang}}') as the language parameter should be passes from outside (you only get users language if you pass it from the outside, like here). --Jarekt (talk) 02:32, 18 September 2016 (UTC)
I was wrong: output of mw.message.new( "lang" ):plain() is not equivalent to frame:preprocess('{{int:lang}}'). --Jarekt (talk) 15:42, 19 September 2016 (UTC)
Resolved
replacing Some usage of c:Module:Wikidata with much much smaller c:Module:Wikidata label fixed the problem. Thanks everyone. Jc86035 after working more on the code I understand your comment about Args and args. That part of the code was wrong, but I was focusing on the expansion depth issue. --Jarekt (talk) 13:52, 20 September 2016 (UTC)

Module:Coordinates (used in other modules)

(Pinging Braveheart.) Module:Coordinates now calls the {{#coordinates:}} parser function through mw.getCurrentFrame():callParserFunction. This unexpectedly broke Module:HS listed building, which calls Module:Coordinates' coordinates.coord function directly. Any way of fixing this? Jc86035 (talk) Use {{re|Jc86035}}
to reply to me
14:46, 20 September 2016 (UTC)

Sensitive IP modules and libLua

I've just started a

discussion at VPT about rolling out the new sensitive IP modules, which might be of interest to people who want to use information about sensitive IPs in other modules or templates. Another item in the proposal which might be of interest is libLua.js, a library for calling Lua functions from JavaScript more easily than is currently possible with the "scribunto-console" API action. — Mr. Stradivarius ♪ talk ♪
14:10, 22 September 2016 (UTC)

Lua table for airports destinations

Hello everyone-that-are-well-of-Lua, any help would be greatly appreciated.

I know that one can pass wikidata<->Lua to write down a wikitable with information issued from wikidata, thanks for Mr Stradivarius.

I've started to work on an idea that would enable multilingual use of Wikidata to build for any airport XXX a table in which all linked airports would appear, and would be always up to date in any language [provided Wikidata is properly filled]. ==> The aim : prevent the fastidious work of updating airport pages.

For instance, this code (in french wikipedia) : {{Aéroport-Destinations|entity=Q17430|property=P521|P521|P931|P137|P521=Aéroport|P931=Ville|P137=Compagnie(s)}} would return the result shown in my page Utilisateur:Bouzinac. This code has been inspired of this one fr:Modèle:Tableau qualificateurs.

I'd like to have a finally simple template {{Aéroport-destinations}} which could be inserted into an airport wiki article.

This template would call a LUA script that will check and return all destinations for the said airport into a table with these properties =>

  • "Airport name in short" (P1813)
  • "City served by airport" (P931)
  • "Airline" (P137)
  • "Start time" (P580), [if destination hasn't started yet, background-color in green]
  • "End time" (P582) [if destination has ended, no line show for this destination/airline OR background-color in red]
  • "Comment and reference(s)" (P2315)+(P854)

This new lua code would be properly working with airports https://www.wikidata.org/wiki/Q17430 or https://www.wikidata.org/wiki/Q642313

Should this new code be working, it would then be adapted to destinations served by one airline.

Any help would be greatly appreciated. --Bouzinac (talk) 12:52, 26 August 2016 (UTC)

I had a go at creating a airport destinations table. It takes into account P931, P137 and P582, but not any of the other properties. If P582 is specified then that line is not processed at all. It is currently limited to show only one airline, just for now. The first argument is used to specify an item id, feel free to play with it as you see fit. Example below.
Script error: No such module "Airport destinations".

--

talk
) 15:18, 28 August 2016 (UTC)

Hi
Snaevar
, thanks for this nice first job. The closure of a destination is properly erased (ex of Réunion-Sydney closed 2008 but Nouméa should still appear as I've put a false end to 2020). May I ask you to add the following, should you have time :
  • use wikitable common formatting (+sortable and hiddable)
  • cite all airlines doing A>B, be them 1 or many, with a comma separating them
  • show a link to relevant wikiarticles
  • present columns in this order : Airport name / City / Airline(s) / Start time (to fill if info exists + green color if not started) / End time (to fill if info exists + red color if closure in the future) / Comments and references.
  • Present columns titles with wikidata, so as to make the lua interlinguical
    • "Aéroport" with the name of Q1248784
    • place served by airport with Q515
    • airline with Q46970
    • début with Q345407
    • end with Q12769393
    • Q1141067 + Q3523102
Are the other properties difficult to insert, as you did not include them ?
I have a question : do you think feasible to automatically present city served by -P931- in a lookup regarding to what has been filled in "Airport name" (P1813) ==> in other words, can one fill only airport name, and automatically have the result of P931, thus one don't need to fill all information ?
Again, thanks to work with me on this developpement! Alex

--Bouzinac (talk) 22:20, 29 August 2016 (UTC)

No other more ideas on this topic ?--Bouzinac (talk) 21:34, 13 October 2016 (UTC)

Historical URL encoding

Is there a way to encode URLs not in UTF-8, but in an older method, like the function de:Wikipedia:Lua/Modul/WLink/en#ansiPercent is doing? If no, can this maybe be imported here? It is needed for Template:Album chart and Template:Single chart, see Template talk:Album chart#Agnetha_Fältskog_name_problem. --Ali1610 (talk) 19:22, 22 October 2016 (UTC)

now imported. Frietjes (talk) 21:49, 23 October 2016 (UTC)

Method of getting logged-in user name?

Hello, Is there any means of getting the screenname of the user looking at the page the module is on? I can't find anything about this in the manual, and it seems like an obvious function that should be part of the language. BigGreenCahuna (talk) 02:06, 27 October 2016 (UTC)

@BigGreenCahuna: No, this isn't currently available, because it would break caching. Caching the same version of a page for all users enables Wikipedia to serve pages to millions of users, without requiring data centers as big as, say, Facebook's. If you were able to add different content for different users, then content would have to be cached per user, rather than per page, which means this performance saving would no longer be possible. — Mr. Stradivarius ♪ talk ♪ 03:51, 27 October 2016 (UTC)

Do you have small Lua related tasks suitable for Google Code-in?

Hi everybody! Google Code-in (GCI) will soon take place again - a seven week long contest for 13-17 year old students to contribute to free software projects. Tasks should take an experienced contributed about two or three hours and can be of the categories Code, Documentation/Training, Outreach/Research, Quality Assurance, and User Interface/Design. Do you have any Lua / template related idea for a task (needs documentation, or some code / code changes) and can imagine enjoying mentoring such a task to help a new contributor? If yes, please check out mw:Google Code-in 2016 and become a mentor! Thanks in advance! --AKlapper (WMF) (talk) 14:38, 8 November 2016 (UTC)

{{Routemap}} seems to be loading rather slowly (especially when there are collapsible sections and/or multiple Routemaps on the same page). This (coupled with the slowness of {{Rail-interchange}}) is causing occasional problems with page size; see Talk:List of New York City Subway terminals. Is there any way to make Module:Routemap (specifically up until row 836) work faster? (Some of its newer bits were written by me; this is likely to be a cause because I learned Lua primarily from editing this module.) —Jc86035 (talk) Use {{re|Jc86035}}
to reply to me
07:17, 13 November 2016 (UTC)

Unfortunately I've got a lot of off-wiki turmoil and won't be able to have a look in any detail for ages. However I notice that a bunch of string.gsub have been replaced with mw.ustring.gsub and the couple of cases I looked at show that the change was not needed. The latter is much slower than the former, although I do not know whether the code using gsub is called often enough to make a difference. For speed, I would be looking at considering an example input and trying to work out what the code does in general terms. Ideally there would be a profiling tool to show which functions it spends the most time in—as there isn't, it needs someone who understands the code to try and guess which functions might be involved. I have seen some poorly designed modules which loop to locate needed information, but this module is too complex for me to quickly see what is going on. Do you know of places in the module which need to loop to process one item? Re string.gsub: I could explain, but a simpler step would be to copy the module into a sandbox and change all the ustring stuff back to plain gsub. Don't worry if it breaks something (some of them might be needed). The question is, does it show a significant difference in the wgPageParseReport in the html source of a page using the module. Johnuniq (talk) 09:29, 13 November 2016 (UTC)
@Johnuniq: There are several places where Sameboat and I (possibly YLSS, although inactive now) added loops (lines 161–191; 785–797; and 1023–1049 (exc. 1033–1036)) which are likely unnecessary and could be replaced with tables (however, only the second is usually loaded). There are also things like overuse of .. .. concatenation where string.format might be faster (not sure about table.concat, which is also used quite a bit). Is the only difference between string.function and mw.ustring.function that ustring allows non-ASCII characters, or am I missing something? Note that I don't really understand lines 492–660, which seems to handle collapsible sections and sidebar column widths.Jc86035 (talk) Use {{re|Jc86035}}
to reply to me
11:08, 13 November 2016 (UTC)
I have done a very quick test to compare a regular Routemap diagram in both en.wp and zh.wp, (the Chinese version module isn't updated to the last version of English and remains 28,822 byte large compared to 66,511 bytes of the English version). The funny thing is that the diagram in zh.wp actually has slightly greater Post-expand include size which I believe to be the main reason of template size limit. So I would say we simply should not have a page to include more than 30 Routemap diagrams, it just can't handle that much. Also converting all BS-map to Routemap helps as BS-map contributed about 740k bytes to post-expand include size in List of New York City Subway terminals version 746203358, but then the Routemap diagrams alone used 1,639,493 bytes out of 2,097,152 already. -- Sameboat - 同舟 (talk · contri.) 12:21, 13 November 2016 (UTC)
@Jc86035: I read your original post hurridly and latched on to the slow aspect. However, it seems the real problem is size (which has the side effect of slowing things down). If there is something specific you would like me to look at, please say so, however my guess would be that Sameboat is correct, namely that each page is limited to 2 MB and that may be the fundamtal issue. If templates/modules are arranged so that the same text is processed multiple times (say one template calls another which calls something else), it may be that 500 KB of final wikitext is expanded to 2 MB during processing, with slowness or a "size exceeded" error.
Regarding speed (although I no longer think that is relevant): string.format is sure to be slower than string concatenation; table.concat is good, particularly when joining many items because it calculates and assigns a buffer to handle the final required size of the concatenated strings.
Re gsub, consider mw.ustring.gsub(overlapProps[i].abbr, '"', '&quot;')
That should be simply string.gsub(overlapProps[i].abbr, '"', '&quot;') regardless of what text is being processed. It works because MediaWiki uses UTF-8 to encode text. For another example, it is also fine to do stuff like string.gsub(text, '-', '–') (changes hyphen to Unicode en dash) or string.gsub(text, '−', '-') (changes Unicode minus to hyphen). You need mw.ustring when the regex needs to treat alternatives as characters, say if the pattern is [aä] which wants to search for a or ä. Lua regards the latter as two bytes (the UTF-8 encoding of ä), and string.gsub would search for any of the three bytes (one for a and two for ä). I have not done any testing, but I have a vague idea of what mw.ustring has to do, and it would be much slower, although that would only matter if gsub is executed many times in a loop. Johnuniq (talk) 01:16, 15 November 2016 (UTC)
@
Template:HK-MTR route/East Rail. Not sure why, although maybe it's because the ECML diagram doesn't use the {{BStext}}-type cells which I added (parts of 209–373). Jc86035 (talk) Use {{re
|Jc86035}}
to reply to me
11:07, 19 November 2016 (UTC)

Help with Module

Hello. I need help for Module. el:Module:Περισσότερεςκατακτήσεις (is in English).

See Cypriot First Division (Q155965), property 1346, qualifier P1355. I want to show the item of P1346 if it has the largest qualifier P1355. Xaris333 (talk) 23:59, 26 November 2016 (UTC)

Listing search results from a Lua module

Hi all. :-) Special:Search/cat s and dog in curly braces does not transclude the list of search results. Does Lua have access to search results lists? (I recall that it does not have API access, but apart from that, I have difficulty finding what relevant access or objects it does have.) --Gryllida 01:45, 9 December 2016 (UTC)

No, I believe modules have no access to Special pages. If you describe the intended purpose, someone might have a suggestion. Johnuniq (talk) 02:01, 9 December 2016 (UTC)
WP:AWIZ
has a section on checking whether the page already exists:
I find it rather annoying that the user needs to leave the wizard to start searching. Were it possible to list the results using a template or anything without JavaScript, that'd be an advantage. (Alternatively, I'd edit the links pointing to that page to add a '?withJS=' parameter, and load a JavaScript which does the task interactively. However, I think that would be a last resort only, and doing it server-side would be neater.) --Gryllida 03:38, 9 December 2016 (UTC)
This needs to be done with JavaScript. You don't have to use ?withJS=, though. You can simply create a default-on JavaScript gadget that only runs when you are viewing that page. — Mr. Stradivarius ♪ talk ♪ 05:10, 9 December 2016 (UTC)

Module:PropertyLink MfD

An editor has nominated Module:PropertyLink for deletion. Input from those familiar with modules is welcome at Wikipedia:Miscellany for deletion/Module:PropertyLink. Thanks, — Godsy (TALKCONT) 09:11, 20 December 2016 (UTC)

User contributions

Is it possible to retrieve the date & time of a user's most recent edit? This would be found at Special:Contributions/USERNAME .. or the data returned by API:Usercontribs --

C
17:42, 23 December 2016 (UTC)

No. Lua has no access to the API or Special pages. You would have seen T154042 from WP:VPT but Scribunto development is very conservative because of its potential impact on the servers. Johnuniq (talk) 21:54, 23 December 2016 (UTC)

How mw.html.tag() works?

For example:

local tab = mw.html.create('table')
tab
    :addClass('wikitable')
    :tag('caption'):wikitext('something '):wikitext('and something')
    :tag('tr'):tag('td'):wikitext('a')
    :tag('tr'):tag('td'):wikitext('b')
return tab

Why it knows that I want to get:

<table class="wikitable">
 <caption>something and something</caption>
 <tr><td>a</td></tr>
 <tr><td>b</td></tr>
</table>

rather than:

<table class="wikitable">
 <caption>something and something
  <tr><td>a
    <tr><td>b</td></tr>
  </td></tr>
 </caption>
</table>

Where the :tag('caption') is closed?--

talk | changes
) 06:01, 15 October 2016 (UTC)

The Sribunto HTML library method mw.html.tag() doesn't perform any sort of "smart" closure of tags. The problem is that you accidentally misinterpreted the output of your code. When I run the code sample you provided I get the following output...
<table class="wikitable"><caption>something and something<tr><td>a<tr><td>b</td></tr></td></tr></caption></table>
...which is equivalent to...
<table class="wikitable">
	<caption>something and something
		<tr>
			<td>a
				<tr>
					<td>b</td>
				</tr>
			</td>
		</tr>
	</caption>
</table>
... which is the same as your "rather than" output. So, everything is working as expected. If you actually want code that outputs HTML equivalent to your first sample, you could do the following...
local tab = mw.html.create('table')
tab:addClass('wikitable')
tab:tag('caption'):wikitext('something '):wikitext('and something')
tab:tag('tr'):tag('td'):wikitext('a')
tab:tag('tr'):tag('td'):wikitext('b')
...which outputs...
<table class="wikitable"><caption>something and something</caption><tr><td>a</td></tr><tr><td>b</td></tr></table>
If it helps to show what is going on, the following code outputs the same HTML as the code immediately above:
local tab = mw.html.create('table')
tab:addClass('wikitable')
local caption = tab:tag('caption')
caption:wikitext('something ')
caption:wikitext('and something')
local tr1 = tab:tag('tr')
local td1 = tr1:tag('td')
td1:wikitext('a')
local tr2 = tab:tag('tr')
local td2 = tr2:tag('td')
td2:wikitext('b')
RP88 (talk) 09:44, 15 October 2016 (UTC)
If your first code box is what you're seeing in your browser, it's probably due to HTML Tidy fixing the broken HTML. SiBr4 (talk) 14:08, 16 October 2016 (UTC)
What does the code look like if you have a table nested with in the "tab" table in the example above? How do I create nested tables and ensure that all the tags get closed? Any examples would be greatly appreciated. Julialturner (talk) 07:03, 4 January 2017 (UTC)
@Julialturner: mw.html closes all of the tags automatically, so you don't have to worry about that. Creating nested tables is just like creating any other HTML structure with mw.html - if you put a <table> node inside another table's <td> node, then that's your job done. The part that usually confuses people is that every time you call :tag() mw.html returns a new node. This can have unexpected results if you don't know how it works. For example:
-- Example 1
local t1 = mw.html.create('table')
t1:tag('tr'):tag('td'):wikitext('foo') -- t1 points to the "table" node because we defined it on the line above.
mw.log(tostring(t1)) -- Logs "<table><tr><td>foo</td></tr></table>"

-- Example 2
local t2 = mw.html.create('table'):tag('tr'):tag('td'):wikitext('foo') -- t2 points to the "td" node, as that is the return value of the expression
mw.log(tostring(t2)) -- Logs "<td>foo</td>"
I'll explain this a little bit. Whenever we "chain" methods like this (e.g. foo:bar():baz()) the expressions are expanded from left to right. I find it easiest to visualise what's happening if I add more parentheses, like this: ( foo:bar() ):baz(). In effect, we are hoping that foo:bar() returns an object that has a "baz" method, and then attempting to call that method. Because of this, the overall return value of an expression with chained methods is the return value of the right-most method. Let me break down my example above.
mw.html.create('table') -- Returns a table node
	:tag('tr')          -- Calls the table node's "tag" method, and returns a new "tr" node
	:tag('td')          -- Calls the "tr" node's "tag" method, and returns a new "td" node
	:wikitext('foo')    -- Calls the "td" node's "wikitext" method, and returns the "td" node
The right-most method is the "wikitext" method of the "td" node, and as this returns the "td" node, that is the overall return value of the expression. The difference between example 1 and example 2 is that in example 1 we are not assigning the value of the expression to any variables, but in example 2 we are assigning it to the t2 variable. Hence in example 1, t1 points to the "table" node, but in example 2, t2 points to the "td" node. Now, as to how we make a nested table, first I'll give you an example.
local root = mw.html.create('table')
	:tag('tr')
		:tag('td')
			:wikitext('The first cell of the first row.')
			:done()
		:tag('td')
			:wikitext('The second cell of the first row.')
			:done()
		:done()
	:tag('tr')
		:tag('td')
			:wikitext('The first cell of the second row.')
			:done()
		:tag('td')
			:wikitext('The second cell of the second row. This cell has a nested table in it.')
			:tag('table')
				:tag('tr')
					:tag('td')
						:wikitext('The first cell of the first row of the nested table.')
						:done()
					:done()
				:done()
			:done()
		:done()
	:done()
Here we use the "done" methods to work our way back up to the original table element. You can avoid the final :done() calls if you make sure that root always refers to the original table element:
local root = mw.html.create('table')
root
	:tag('tr')
		:tag('td')
			:wikitext('The first cell of the first row.')
			:done()
		:tag('td')
			:wikitext('The second cell of the first row.')
			:done()
		:done()
	:tag('tr')
		:tag('td')
			:wikitext('The first cell of the second row.')
			:done()
		:tag('td')
			:wikitext('The second cell of the second row. This cell has a nested table in it.')
			:tag('table')
				:tag('tr')
					:tag('td')
						:wikitext('The first cell of the first row of the nested table.')
Or if you want to be able to access either table at any time, you can do something like this:
-- Make the root table and store a reference to it in the rootTable variable
local rootTable = mw.html.create('table')

-- Add a row to the root table
rootTable
	:tag('tr')
		:tag('td')
			:wikitext('The first cell of the first row.')
			:done()
		:tag('td')
			:wikitext('The second cell of the first row.')

-- Add a second row to the root table, and make a reference to the nested table's "table" node
local nestedTable = rootTable
	:tag('tr')
		:tag('td')
			:wikitext('The first cell of the second row.')
			:done()
		:tag('td')
			:wikitext('The second cell of the second row. This cell has a nested table in it.')
			:tag('table')

-- Add a row to the nested table.
nestedTable
	:tag('tr')
		:tag('td')
			:wikitext('The first cell of the first row of the nested table.')

-- Add a third row to the root table
rootTable
	:tag('tr')
		:tag('td')
			:wikitext('The first cell of the third row.')
			:done()
		:tag('td')
			:wikitext('The second cell of the third row.')

-- Add another row to the nested table
nestedTable
	:tag('tr')
		:tag('td')
			:wikitext('The first cell of the second row of the nested table.')
This has been a long post - hope it helps! — Mr. Stradivarius ♪ talk ♪ 13:33, 4 January 2017 (UTC)
@Strandivarius: Thank you so much for all the examples. I have done something like the first example of the nesting without really know what I was doing. It works most of the time, but it was brought to my attention that some of the end tags weren't produced in the raw html (Module:Infobox_gene). It renders correctly in wikipedia, but if you look at the html it is missing some end tags. I am in the process of looking for missing :done(), based on what you have told me here. — Preceding unsigned comment added by Julialturner (talkcontribs) 19:01, 4 January 2017 (UTC)
Fantastic post by Mr. S! When playing with mw.html I found it useful to dump (pretty print) the results. See Module:Dump#Dump of a formatted html string. It would be helpful if you could put some code in a sandbox that demonstrates the problem, with a dump. Johnuniq (talk) 23:58, 4 January 2017 (UTC)

Moving

I saw User talk:Peter coxhead#Testcases page in mainspace and tried to move it to Module space. However, when I tried I got "Non-Module pages cannot be moved to the Module namespace (except for /doc pages), and Module pages (except for /doc pages) cannot be moved out of the Module namespace." and it deletes the target page without letting you know what it has done. How do you move stuff over. I figure you could move it to a Module:something/doc and then to the correct title but I've done enough screwing around for now. CambridgeBayWeather, Uqaqtuq (talk), Sunasuttuq 03:43, 30 December 2016 (UTC)

@CambridgeBayWeather: It cannot be moved to the module namespace; however, it should not remain in mainspace since it is not an article. With the exception of /doc, all pages in the module namespace must be Scribunto, not wikitext. Module /testcases are written in Lua (Module:Autotaxobox/testcases), not wikitext. — JJMC89(T·C) 06:29, 30 December 2016 (UTC)
So how is it moved so as to keep the history intact? CambridgeBayWeather, Uqaqtuq (talk), Sunasuttuq 06:34, 30 December 2016 (UTC)
@CambridgeBayWeather: You move it with the usual "Move" link, just like with any other page. You just can't move it to the module namespace, as a) it's impossible and b) it wouldn't make sense, as it isn't a Lua module. Most test cases pages of the kind in question are kept in the Template namespace. There are some test cases in the Module talk namespace, but these are generally reserved for those generated from a test case module located in the Module namespace. — Mr. Stradivarius ♪ talk ♪ 10:01, 30 December 2016 (UTC)
Thanks. CambridgeBayWeather, Uqaqtuq (talk), Sunasuttuq 21:05, 30 December 2016 (UTC)

Can you test a Lua module out of your user space?

I've tested templates in my user space, by using {{User:TJRC/Sandbox/TemplateName}}. It looks like you can't do that with modules, i.e., with something like {{#invoke:User:TJRC/Sandbox/Modulename|func}}. Is this correct? I just want to check before I create something in Special:PrefixIndex/Module:Sandbox. TJRC (talk) 01:11, 7 January 2017 (UTC)

Modules must exist in the Module name space so you can sandbox your project in Module:Sandbox.
Trappist the monk (talk) 01:26, 7 January 2017 (UTC)
For an example, see Module:Sandbox/Johnuniq/testpre and edit its talk page to see how it calls the sandbox module. That page was originally set up to test what happens when a <pre> block is returned by a module, but I should have used a more generic name because I have used it for lots of small tests, mostly without saving anything. I write some code to test a point I'm working on, edit that page but don't bother saving. Instead, under "Preview page with this module" enter "Module talk:Sandbox/Johnuniq/testpre" for the Page title and click "Show preview". Of course if you are building a larger module you can save and muck around, but the the preview feature is very handy. Johnuniq (talk) 01:41, 7 January 2017 (UTC)
Thanks to both of you. That's what it looked like to me, but I wanted to be sure. TJRC (talk) 01:49, 8 January 2017 (UTC)
actually, it _is_ possible to test lua modules not from the module namespace, and use your user namespace instead.
this is a very poorly publicized, but beautiful feature of Special:TemplateSandbox. from there, you define a "prefix", such as "User:TJRC/Sandbox". once the prefix is defined, you create your "sandbox modules" and "sandbox templates" like so: User:TJRC/Sandbox/Module:testmodule and User:TJRC/Sandbox/Template:testmodule (_do not forget the colon!). now, when invoking {{#invoke:testmodule| bla | blabla }}, or when transcluding {{testtemplate | param ... }}, it will look first for pages under the prefix/Module: and prefix/Template:, and will use those when exist. this means you can test deeply nested stuff: let's say page a transcludes template b which in turn transcludes c and so on, and eventually, template Z invokes modules alfa, beta and gamma.
you can create sandbox doppelgangers for template Q (in the middle of the transclusion chain), and for modules beta and gamma, but _not_ alfa, and then "preview" page A from the Special:TemplateSandbox, and it will Do The Right Thing(tm).
disclaimer - it's been a few years since i _actually_ used this feature. i believe it still works.
HTH, peace - קיפודנחש (aka kipod) (talk) 22:49, 10 February 2017 (UTC)

Testing a template/a module that takes parameters from parent

Hi, I am wondering how I can test a module like module:labels that contains functions that doesn't take parameters but rather fetches the parameters from the parent scope - in this case a template instantiation. Can I use Module:UnitTests for this? Moberg (talk) 20:11, 21 February 2017 (UTC)

Unclear which module you mean, but you can use Template preview with any template or module. To do this make your changes to the module, then to test them enter the full name (so prefix any template with 'Template:') of the template or page it is used on in the box below, labeled "Preview page with this template" and click 'Show preview'. You should see that page, but with your modifications to the module (or template) used in place of any instances of it. This also works with the sandbox, to let you test changes there before committing them to the main module or template.--JohnBlackburnewordsdeeds 20:29, 21 February 2017 (UTC)
Sorry, definitely unclear. I mean this module: [1]. And about testing, what I mean was not previewing, but writing unittests with Module:ScribuntoUnit for example. Is that possible? Moberg (talk) 20:41, 21 February 2017 (UTC)
@Moberg: Could you say which specific functions you are talking about? Usually parameters from templates are fetched using frame.args, but I don't see that anywhere in the module. — Mr. Stradivarius ♪ talk ♪ 23:33, 21 February 2017 (UTC)
My guess is that testcases for wikt:Template:label are wanted, and that template ends up calling wikt:Module:labels/templates which uses wikt:Module:labels in a manner I have not investigated. Johnuniq (talk) 00:17, 22 February 2017 (UTC)
Yes I wanted to test the template because I'm not sure how I could test the module since it doesn't take any direct parameters. I wrote some tests at Swedish Wiktionary using UnitTests, but if possible I would like to try out Module:ScribuntoUnit Moberg (talk) 08:03, 22 February 2017 (UTC)

Lua request

Hey,
I was wondering if there is a way to find how many lines does a text contain.
for example:

a
b
c

would give 3
Thanks--Mikey641 (talk) 12:00, 22 February 2017 (UTC)

@Mikey641: Yes, you just need to count the newline characters in the text, then add one to get the number of lines. string.gsub has a count feature built in, so it's probably easiest to use that. This code should work:
local function countLines(s)
	local _, count = s:gsub('\n', '%0') -- Count newline characters in s
	return count + 1
end
Let me know if you have any questions about it. Hope this helps. — Mr. Stradivarius ♪ talk ♪ 14:40, 22 February 2017 (UTC):::
@Mr. Stradivarius:. Thank you. I have one question: I put the code in he:יחידה:מונה הופעות so how am I suppose to use it? as {{#invoke:מונה הופעות|countLines|WHAT PARAMETER??}} like what parameter is the string? thank you very much--Mikey641 (talk) 14:57, 22 February 2017 (UTC)
@Mikey641: The function as I wrote it above isn't accessible from wikitext - it's only accessible from other Lua functions in the same module. I've changed your module in this edit so that countlines can take arguments from wikitext. You can call it using {{#invoke:מונה הופעות|countlines|text goes here}} or {{#invoke:מונה הופעות|countlines|text=text goes here}}. Best — Mr. Stradivarius ♪ talk ♪ 23:27, 22 February 2017 (UTC)
thank you very much!!!--Mikey641 (talk) 06:12, 23 February 2017 (UTC)

Cached module expansion

Hi, in itwiki we were wondering if the expansion of a module is cached by the MediaWiki parser or not. Let's say page A includes ten times {{#invoke:B|main}}. Is the main function in module:B executed once or ten times? I would say "ten times", but I don't know parser internals. The module could contain randomly generated content or os.time(), so the parser can't cache it, or is it able to be aware of these functions? --Rotpunkt (talk) 16:11, 25 February 2017 (UTC)

Yes, module B is loaded and executed ten times. You can demonstrate that by the fact that some (sloppy IMHO) modules have pseudo-global variables at the top, like local count = 10 and functions then use and change count. However, count is always 10 when the module starts—nothing is shared between the separate calls to module B. The good news is that it is astonishingly fast. Module:Convert is breathtakingly enormous and complex yet well over 1000 {{convert}} calls can be executed on a single page.
If module B contains only read-only data, and if it is likely it may be used several times on a page, the module can be loaded into memory once, and the same copy will be used for each of the ten times it is called. That uses mw.loadData instead of require. Johnuniq (talk) 00:43, 26 February 2017 (UTC)
So, knowing that mw.loadData( module ) does not support functions, a module that does not use global variables actually it is not recognized as "functional", calling it only 1 time in the whole page. I'm right? --Valerio Bozzolan (talk) 04:01, 26 February 2017 (UTC)
I don't understand that. If a module contains only read-only data, it can be loaded with loadData. The first call on the page will load the module (and check that it contains only data). Subsequent calls on the same page will use the cached result from the first load. However, if a module is called via #invoke or require, a fresh copy of the module will be loaded each time the module is used. One way to think about it is to know that part of the design criteria for MediaWiki is that a snippet of wikitext should render to the same html output regardless of context. For example, something like {{example|one|two}} would give exactly the same result regardless of anything else on the page—it does not matter if the template being rendered is the first occurrence on the page or the tenth. MediaWiki is like that because the designers want section editing to work (say for preview) without having to process the whole page. Johnuniq (talk) 06:55, 26 February 2017 (UTC)
There are several steps to invoking a module:
  1. Load the source of the module from the wiki page.
  2. Load the module source into Lua, which produces an "init chunk" function in Lua.
  3. Execute the "init chunk" to actually create the functions.
  4. Execute the invoked function.
Steps 1 and 2 happen once per page. 3 and 4 need to happen each time the module is invoked, to prevent one invoke from affecting the next. Requiring another module from within Lua does basically the same thing. mw.loadData does all steps only once and relies on the read-only wrapping to prevent one invoke from affecting the next. Anomie 15:26, 26 February 2017 (UTC)
Sorry if I repeat myself: I'm asking if there is any way to declare a function that the parser can safetly cache its output jumping all these 4 steps. E.g. sqrt(5) is the same even if you call it 1000 times, no reasons to calculate it even in these last 2 steps. So, no way to instruct the parser about the existence of "functional" functions, which result that can be safetly cached when arguments are the same? --Valerio Bozzolan (talk) 23:39, 26 February 2017 (UTC)
No, there is no way to do that. Anomie 01:12, 27 February 2017 (UTC)
@Johnuniq @Anomie Thanks for the detailed answers! --Rotpunkt (talk) 08:47, 27 February 2017 (UTC)

Smart formatnum?

It was pointed out at Template talk:when#Breaks inside Infobox settlement that if you try to pass various inline cleanup templates through infoboxes which apply {{formatnum: }} that the year in the tracking category is mangled (comma inserted). would it be a good idea to create a smart formatnum which excludes the categories, and say references, from the formatnum transformation? or, does this already exist? thank you. Frietjes (talk) 22:14, 27 February 2017 (UTC)

maindate2

A trivial change (I suspect) is needed to a Lua module; please see Template talk:Article history#maindate2. Any takers? - Dank (push to talk) 03:14, 28 February 2017 (UTC)

Calling Mr. Stradivarius. The module is very sophisticated and mucking about with it could introduce a bunch of bad side effects. Johnuniq (talk) 04:19, 28 February 2017 (UTC)
Thanks John. - Dank (push to talk) 04:20, 28 February 2017 (UTC)

Wikidata: Extract a property from an item's property item

Hi,

I'm not sure if it's the right place to ask about this: is there any way to extract say the country property (P17) from the item linked to the headquarters location property (P159) of an item? For example, the headquarters location property of Nordea is Stockholm ; if we then look for the country property of Stockholm, we'll get Sweden. So if could get the country that way, we wouldn't need to set a country qualifier for the headquarters location property of Nordea, is there any way to do that? The RedBurn (ϕ) 21:40, 1 March 2017 (UTC)

@RexxS: Any thoughts? Johnuniq (talk) 00:34, 2 March 2017 (UTC)
Sure, John, I made a call in my sandbox module, Module:RexxS called getValueIndirect, that takes two property IDs as the first and second unnamed parameters, and returns the value of the second property of the value of the first property for the current article. So previewing a call for the country (P17) of the value of headquarters location (P159) in Nordea will give you:
  • {{#invoke:RexxS|getValueIndirect|P159|P17}} → Finland
(you can add a |qid= for testing the call outside of the current article). The value of headquarters location (P159) in Nordea (Q1123823) is Stockholm (Q1754); and the value of country (P17) for Stockholm (Q1754) is Sweden (Q34). I'm just taking the first value of each property, assuming they are single-valued. You'd have to specify how you'd want to handle the situation if either were multi-valued.
The call is intrinsically expensive because it has to call another entity not the one connected to the current article. Note that the property headquarters location (P159) in Nordea (Q1123823) already has a qualifier, country (P17), set to Sweden (Q34) and it is clearly preferable in Lua to fetch that qualifier, when present. In this particular case, Nordea (Q1123823) also already has the property country (P17), set to Sweden (Q34), which is even simpler to extract. I suppose you could check if the article's Wikidata entry has the country set; if not, check if it has the country qualifier of the headquarters location set; if not, then make this indirect call. I think I'd want to know what was trying to be achieved before I went to that much effort. --RexxS (talk) 02:02, 2 March 2017 (UTC)
Thanks for all that trouble. Johnuniq (talk) 02:26, 2 March 2017 (UTC)
No trouble. It saves my old brain from going rusty. --RexxS (talk) 02:36, 2 March 2017 (UTC)
Awesome, thanks! About directly fetching the property country (P17) of an item, it's no always a good idea, for instance with d:Q67#P159 which is in France, but the main P17 value is multiple countries. It has been suggested to split that property into city, etc. but some users think the headquarters value should be as specific as possible (e.g. building for instance) - which actually makes it more difficult to use since we have to check what it represents - and that we should do a lot of expensive getValueIndirect calls to get the city, (state or other), and country. I thought about asking to auto set the country for P159, but if it's a building (or even a room in a floor of a building) instead of a city, it's not that easy. The RedBurn (ϕ) 13:02, 2 March 2017 (UTC)

<ref>...</ref> ?

Hi everyone! I'm trying to create an option in Module:Wd that adds references from Wikidata to claims from Wikidata. However, simply outputting a reference between the tags <ref>...</ref> from a module keeps these tags as plain text; they are not processed by Wikipedia. This differs from templates, where such output is actually processed and converted into a real reference.

Is there any way to add references from a module? Or am I condemned to using templates for this?

Thanks, thayts💬 13:10, 9 December 2016 (UTC)

Look at Module:Footnotes, particularly the return value from f.sfn().
Trappist the monk (talk) 13:16, 9 December 2016 (UTC)
You might wish to review Module:Video game wikidata and especially buildCite (which can probably be changed to include Module:Citation/CS1 directly via require()). That said, is there a reason you aren't e.g. working in Module:Wikidata/sandbox? We don't really need two general purpose Wikidata modules. --Izno (talk) 13:44, 9 December 2016 (UTC)
The technical reason that this does not work is that Lua doesn't do any preprocessing of module output. Arguments are preprocessed before they are passed to Lua, but unless you tell it otherwise, Lua just outputs regular strings. This is mostly for performance reasons, but also because (although it shouldn't in general) preprocessing things twice may cause some things to break. To preprocess things inside Lua, you need to use methods in the frame object. You could do it with frame:preprocess('<ref name="foo">bar</ref>'), but it is more efficient if you do it with frame:extensionTag{name = 'ref', content = 'bar', args = {name = 'foo'}}, as it avoids the overhead of the parser having to parse the HTML tags and preprocess whatever content you put inside them. — Mr. Stradivarius ♪ talk ♪ 01:10, 10 December 2016 (UTC)
Thank you all very much for the examples and explanation. I created this module because I wanted to provide an alternative that is more intuitive (still working on that) and more logical (why if I call a module called "Wikidata" must I supply "FETCH_WIKIDATA"... the problem that it's trying to address should be addressed one level higher), but mostly because I wanted to learn how to create a module and I found it a waste not to share it with those who might prefer to use it. Thanks, thayts💬 16:41, 10 December 2016 (UTC)
@Thayts: Sorry for the late reply, but I only just noticed your implied question, why if I call a module called "Wikidata" must I supply "FETCH_WIKIDATA"? The problem is that we only have permission to use Wikidata in infoboxes, and only then with the proviso that local data should take precedence. That means that there are three possible outcomes for a given field in an infobox: (1) the field displays with a value supplied locally; (2) the field displays with a value supplied from Wikidata; (3) the field does not display at all. The third outcome happens through the infobox logic whenever the parameter is empty or missing, and it may be that the parameter is explicitly set to be empty in an article to ensure that the field is not displayed. Given all that, how would you suggest the template logic should be arranged so that we can fetch the value from Wikidata without using a "special" value to trigger it? I couldn't see a simple way in 2013 when the module was originally written, so I settled for having a trigger value that wouldn't be at all likely as a locally supplied value. I'd be happy to hear your solution. --RexxS (talk) 03:17, 2 March 2017 (UTC)
@RexxS: I would come up with something like User:Thayts/sandbox/1 as included at User:Thayts/sandbox/2. I've added the "nowikidata" parameter to accommodate for outcome number 3 in case the parameter is missing. I suppose with your solution you would need a similar parameter (but then the opposite "fetchwikidata") because otherwise you wouldn't be able to fetch from Wikidata at all as you describe it. thayts💬 17:11, 4 March 2017 (UTC)
@Thayts: So your solution to catering for all three different options would be to use another parameter? You mean a bit like Module:WikidataIB does? Doesn't that make your criticism of the way Module:Wikidata works just a matter of your personal dislike of using a special value for a parameter, as opposed to having another parameter? Couldn't somebody equally complain "Why must I supply |nowikidata=true/false when I call the module"? If you don't like using a special parameter value in the way that Module:Wikidata does, you have a perfectly good alternative in Module:WikidataIB that also addresses the "opt-in" vs "opt-out" issues. --RexxS (talk) 21:37, 4 March 2017 (UTC)
@RexxS: Well, I don't see a particular benefit to the extra parameter and if it were up to me I would leave it out. It was just a way to accommodate for how you would like to have it (you do need something extra too anyway). I'm not trying to convince anyone here of what would be the best way, all I'm saying is that in my opinion a toggle whether to fetch from Wikidata or not should not be part of a module that is designed particularly for fetching from Wikidata. thayts💬 22:16, 4 March 2017 (UTC)
Well, unfortunately, as you can see from your own experiments, it is necessary to allow the template calling the module to toggle whether to fetch from Wikidata or not, in some way. Incorporating that logic into the module is far more efficient than hard-coding the testing into every separate infobox template that calls the module. --RexxS (talk) 22:38, 4 March 2017 (UTC)
@RexxS: Like I said, I see no benefit in the extra parameter and so neither in the toggle (in the particular case of infoboxes). Then where you would do something like {{#invoke:wikidata|{{{country|FETCH_WIKIDATA}}}}} I would do something like {{{country|{{#invoke:wd}}}}} and so there is no real difference (except that the latter doesn't do a superfluous call to a module). thayts💬 22:45, 4 March 2017 (UTC)
And if you'd really need to have a toggle at multiple places, then simply wrap the module inside a template that provides such a toggle and include that template instead. thayts💬 22:59, 4 March 2017 (UTC)
Of course there's a difference. We originally tried supplying the wikidata whenever there was no local parameter supplied as you suggest, but quickly found that editors insist on having control over whether a value from wikidata was fetched. See
Wikipedia:Wikidata/2017 State of affairs
for an idea of how your suggestion would be received.
Why on earth would anybody write the toggle logic using parser functions and then wrap that around a Lua module that can do the same toggle a thousand times more efficiently? There's no use for the module without the toggle (we can only fetch Wikidata for use in infoboxes), so why wouldn't it be part of the module? --RexxS (talk) 23:14, 4 March 2017 (UTC)
I'm not suggesting anything. My module is just a building block. You can use it in any way you want. And that's all there is to it. thayts💬 23:41, 4 March 2017 (UTC)

Leakage

I am working on a location map wrapper in Module:Australian place map for use in Template:Infobox Australian place. I have implemented the module in the sandbox, and now in Template:Infobox Australian place/testcases I am seeing something strange. in particular, in the "Nyabing" I am currently seeing two pin markers, and in one of the "Woy Woy" examples, I am seeing zero pin markers. basically, it looks like the pin from the first "Woy Woy" has migrated up the page to the "Nyabing". my guess is that this is some quirk with using the {{Testcase table}} template and/or something odd going on in Module:Location map? on a related note, I imagine it would probably be better if I could call the main function in Module:Location map directly instead of going through expandTemplate? I am hoping Jackmcbarn or one of the other LUA experts can help. thank you. Frietjes (talk) 16:41, 4 March 2017 (UTC)

@Frietjes: It looks as if it is a simple mistake in Template:Infobox Australian place/testcases which has two Woy Woy tables, one with latd = -33.49 and that puts the pin a long way off the map. Johnuniq (talk) 00:56, 5 March 2017 (UTC)
Much later, something inside me muttered "oops, latitude is negative in Australia". Then I did a test and saw that {{Infobox Australian place}} gives identical results regardless of whether latd is positive or negative, so I looked at the template and see it is using #expr:abs to ignore the sign of latd. However, Module:Australian place map applies abs to the longitude rather than the latitude. Some mucking around makes me think you probably want abs(longitude) to avoid an ugly error message if a negative longitude is entered. However, the module needs the same for latitude, and that is why the pin is in the wrong place with the negative latitude. Johnuniq (talk) 09:38, 5 March 2017 (UTC)
Johnuniq, yes, that was dumb on my part. I can't believe I didn't see the fact that I had applied the abs to the long instead of the lat. thank you. Frietjes (talk) 13:57, 5 March 2017 (UTC)

Finding text using string.match on the currently edited page

I'm reuploading a lot of images using Commonist, which unfortunately overwrites file description pages. Is there a way to find text currently in the page (for example, the original uploader's username in the file information template) by transcluding the page, or does that not work because of Lua being parsed at the wrong time? Jc86035 (talk) Use {{re|Jc86035}}
to reply to me
10:34, 5 March 2017 (UTC)

@Jc86035: You can get the wikitext of the current page with mw.title.getCurrentTitle():getContent(). You can also expand any templates etc. in that wikitext by using frame:preprocess. Whether you can manage to get useful information from either or both of those steps is another matter, however. — Mr. Stradivarius ♪ talk ♪ 23:37, 5 March 2017 (UTC)
I have often used 'getCurrentTitle' and 'getContent' (rarely 'frame.preprocess!) in order to do some minimal analysis of pages in WikiVoyage (get TOCs from another page, word analysis, search for a word or phrase, create a gallery of images found on a page in order to see if those images are in 'Commons' etc.) The main issue you will find is that there can be a lot of work actually parsing the page text (text processing) with Lua in order to find and identify what you are looking for. Also be aware of multiple variations and exceptions that you may have to code for. I agree with the above as to whether of not you will be able to obtain any useful information is in question. (note: besides 'string.match', you will also be using a lot of 'string.gsub', 'string.find' commands as well. - Best wishes and Good luck! -- Matroc (talk) 04:56, 7 March 2017 (UTC)

Another Lua request

Hey
I need help creating a module that will order 2 words alphabeticaly.
I did it in wiki code so I will explain how I did it, if you have better sugestions please offer:

  1. First, I created a template called
    Gimatria
  2. Then I took the first 2 letters of each word, if the first letter of X > Y then it will produce the text Y-X
  3. If the first letter of X < Y ==> X-Y
  4. If X=Y, it will do the same for the second letter, then for the third and that's it.
    • Note: before comparing you need to remove the geresh - ', I did it using {{replace}}.

Tagging User:Mr. Stradivarius who has helped me here before--Mikey641 (talk) 21:47, 7 March 2017 (UTC)

@
Gimatria
for only sorting Hebrew words, though, then that's certainly possible. You might try something like the following procedure (should work for any number of words, not just two):
  • Define a function that converts a hebrew character into its Gimatria number.
  • Remove the geresh from the words with string.gsub.
  • Convert the words into one of the unicode normalization forms, using e.g. mw.ustring.toNFD, in case strings which should be identical have different combining characters. (This would mean that they would have different unicode codepoints, which would affect comparisons.)
  • Put the words into a sequence (a Lua table with keys 1, 2, 3, etc.).
  • Sort the sequence using table.sort, specifying a custom sorting function. Your function should:
    • Accept two words.
    • Iterate over the codepoints in each of the words using a while loop and an index i starting at i = 1.
    • Find the i'th character in each of the strings using mw.ustring.codepoint and mw.ustring.char (mw.ustring.char(mw.ustring.codepoint(s, i, i))).
    • Find the Gimatria number for each of those characters, return true if the number for the character from the first string should sort before the one for the second string, and return false if it should sort after. If the Gimatria numbers are equal, keep iterating.
    • If all the Gimatria numbers are the same, the strings are (in effect) equal, so return either true or false. It doesn't matter which, unless you want to order Gimatria-identical strings in some other way as well.
  • When you have sorted your table, you can output it however you want. For example, you could join all the strings together into one big string (with a separator) using table.concat.
Unicode can be a bit tricky so I might have got some of this wrong, but this is the basic idea of what you will need to do. Let me know if you need any more help. Best — Mr. Stradivarius ♪ talk ♪ 02:38, 9 March 2017 (UTC)
  • Interesting discussion. As an aside, I am wondering if besides 'garesh' would you want to replace 'gershayim'. Also, would one have to be concerned that an 'apostrophe 0027' might have been used for the 'garesh' character and 'quotation mark 0022' for the 'gershayim' character. -- Cheers! Matroc (talk) 05:25, 9 March 2017 (UTC)

Gating lua functions

So, we are using a system in hewiki to "verify" template parameters. i will be happy to explain about the system, but my question here is a bot different:

it turns out that this system adds significant load to some template parsing, and this cases a small number of pages to violate some limits of the parser, and these pages then are not parsed correctly.

the only remedy we found so far is to completely (i.e., globally) disable this system - if we do that, the pages are parsed ok.

what we are looking for, is a way to gate specific lua functions, based on the some attribute of the page, something similar to {{

Nobots
}}, for lua modules.

it is perfectly kosher to use something like categories (naturally, it will be a hidden one), i.e., i will be happy to define a new hidden category, say "No template parameters validation", and add those pages to the category. however, i could not find a way to ask in lua "does this page belong to category X", or "give me the list of categories this page belongs to". i cannot think of something other than category that will do the job, but i am willing to learn any new tricks.

note that the #invoke call is not in the page itself, but rather pretty deep in some templates (many may not even be transcluded directly, but through other templates, going 2, 3 and even 4 levels deep).

any help and advice will be appreciated. peace - קיפודנחש (aka kipod) (talk) 16:04, 12 March 2017 (UTC)

@קיפודנחש: While there's no way to find the categories of a page in Scribunto as far as I'm aware, there are two ways of doing this that I can think of. The first is to have a flag in the page content and parse it using something like mw.title.getCurrentTitle():getContent():find('__NOPARAMETERVALIDATION__'). The second is to have a blacklist module with e.g. return {['Page name 1'] = true, ['Page name 2'] = true} which you check before doing the validation. I'd be quite interested in hearing about the system you are using, though - what kind of parameter verification are you doing that's creating so much load? — Mr. Stradivarius ♪ talk ♪ 23:39, 12 March 2017 (UTC)
thanks. your second suggestion is what we actually already do, i.e., keeping a "blacklist" (except we call it "verboten"), and is what i wanted to avoid - i think it would be nicer and better to let pages self-blacklist, and it would require less maintenance. as to your first suggestion, well, it would work, but it would completely miss the point - the whole point of the exercise is to avoid calling getContent() (albeit for the template rather than for the page, but TBH, in most cases, in in all actual cases where we want to blacklist, doing it for the template is actually cheaper....). bottom line: thanks for your suggestions, and i appreciate the thought, but unfortunately, the first one is what we try to avoid, and the second won't work for us....
just to complete the picture, what we do is something like:
local verbotten = {
    ['page name 1'] = '',
    ['page name 2' = '',
-- ..... etc. etc. etc.
}

function envelope( frame )
    local pageName = mw.title.getCurrentTitle().text

-- exploiting the fact that unline JS, in lua '' is actually true
    return verbotten[pageName] or require( 'actualModule' ).actualFunction( frame ) 
end
as to your question: i am not sure 100% about the load, but i suspect it's not from the verification itself, but rather from the fact that mediawiki neglected to create the mw.templateData.getTemplateData( templatename ), which is open for ~ 2 years now. "they" actually put "priorily:lowest" on it (see phab:T107119, so we call getContent() on the template page,, distill the stuff enclosed inside the "templatedata" tag, and call "jsonDecode()" on it. after that, the rest is trivial. you may want to look in he:Module:ParamValidator - i tried to document it as much as possible. the system is working, and exposed thousands (literally) of errors in templates.
peace - קיפודנחש (aka kipod) (talk) 04:30, 13 March 2017 (UTC)
That kind of work should be done by a bot rather than a module that is implementing a template. Johnuniq (talk) 04:44, 13 March 2017 (UTC)
@Johnuniq: - no argument here (except to advocate that this shouldn't even be done by a bot - it's a natural thing for mw:Extension:TemplateData to implement as part of the extension: the whole idea of defining parametr as "required", is to add the page to tracking category when it's missing, same for "type" as number and "obsolete" parameter). unfortunately, the templatedata development team did not do it, and i am not aware of a bot that does it. do you happen to have such a bot? until "someone" implement it in the extension, or "someone" writes a bot, we are sticking with the lua implementation. peace - קיפודנחש (aka kipod) (talk) 04:55, 13 March 2017 (UTC)

Location map / infobox map

There was some discussion at TfD about Template:Infobox map. basically, all that Template:Infobox map does right now is (1) check to see if the map exists, and then (2) call either Template:Location map or Module:InfoboxImage. this is somewhat inefficient since there is already an ifexists check in the getMapParams function in Module:Location map. so, my thought is that we could change the code of {{infobox map}} to something like

{{location map|{{{map}}}
  | relief = {{{relief|}}}
  | overlay_image = {{{overlay|}}}
[...]
  | nomap_message = {{#invoke:InfoboxImage | InfoboxImage | image={{{map}}} | size={{{map_width|}}} | maxsize={{{max_width|}}} | sizedefault={{if empty|{{{default_width|}}}|220px}} | alt={{{map_alt|}}} | title={{{map_caption|}}} }}{{#if:{{{map_caption|}}}|<div>{{{map_caption|}}}</div>}}
}}

so, that instead of returning the error message on line 50 of Module:Location map it would return the value of |nomap_message= if |nomap_message= is not nil. does this seem like a good idea? if so, it would be helpful if someone could implement this |nomap_message= in Module:Location map/sandbox for testing. I would do it, but I am not sure the best way to pass this through to the getMapParams function and the best way to catch it when it comes out of the getMapParams function. probably need a second return flag with 0 for no error, and 1 for error or something like that? thank you. Frietjes (talk) 16:35, 16 March 2017 (UTC)

Module:Navbox with nowrap lists

An editor has asked for a discussion regarding Module:Navbox with nowrap lists. Input from those familiar with modules is welcome at Wikipedia:Miscellany for deletion/Module:Navbox with nowrap lists. Thanks, — Godsy (TALKCONT) 09:11, 20 December 2016 (UTC)

Not Wikipedia:Miscellany for deletion/Module:Navbox with nowrap lists? – Uanfala (talk) 21:21, 21 March 2017 (UTC)
@Uanfala: Corrected, thanks. I borrowed from my format of Wikipedia talk:Lua/Archive 5#Module:PropertyLink MfD above and overlooked that part. — Godsy (TALKCONT) 03:34, 22 March 2017 (UTC)

Replacing HTML character entities with normal characters

How can I modify Module:Tone superscript so that it only adds superscript tags to numbers not part of HTML entities (or filenames/links/anything which breaks when <sup> tags are added)? The module was originally written by someone else but I'm trying to repurpose it so it works in {{Infobox Chinese}}. Jc86035 (talk) Use {{re|Jc86035}}
to reply to me
09:15, 24 March 2017 (UTC)

I looked very quickly. This does not address your question but wouldn't you want the following (note the +):
x = arg:gsub("(%d+)", "<sup>%1</sup>")
I do not understand the scenario. Where would the code be used? That is, would it change some of the parameters to the infobox, or change some of the output? I can't think of a reason why digits should be automatically superscripted.
The heading of this section suggests that code to change an entity to a character is wanted? Is that right? Johnuniq (talk) 09:42, 24 March 2017 (UTC)
@Johnuniq: In the Wade–Giles romanization of Mandarin, tone numbers are superscript, but the tone numbers might not be superscripted by users. The output of {{Infobox Chinese/Chinese}} would be changed. The original author didn't bother with the +, which isn't really a problem since there are fewer than 10 tones in most tonal languages. The module could have the entities changed to characters to avoid inserting <sup> tags in them, although there could be a better solution. Jc86035 (talk) Use {{re|Jc86035}}
to reply to me
12:37, 24 March 2017 (UTC)
If I understand this correctly, you want to be able to parse arbitrary wikitext input, discard the parts that have a special meaning in wikitext, and alter the other parts? Unfortunately, in the general case at least, this requires a wikitext parser, and no-one has written a wikitext parser in Lua yet, as far as I know. In some cases you may be able to muddle through, but to do it accurately, you need a parser. If I were writing a module like this, then rather than trying to parse everything, I would be inclined to be strict about what input the module accepts, and then raise an error if the module detects invalid input. You can make this error a silent one at first (just adding a tracking category) to avoid generating too many pages with big red error notices. — Mr. Stradivarius ♪ talk ♪ 15:28, 24 March 2017 (UTC)
An infobox at Jackie Chan includes the wikitext:
| j3 = {{Jpingauto|Can4 Gong2 Sang1}}
Template:Jpingauto is a redirect to {{Tone superscript}}, and the above example outputs Can4 Gong2 Sang1.
Is the proposal that the template would be retained but would be modified to avoid damaging certain parameters?
Or, is the proposal that the code from the module would be integrated into the infobox so that the template is not needed?
Or, something else?
Assuming the template would be retained, as Mr. Stradivarius says, a general solution would be too complex. However, if the template only has to handle an input that might have entities like &#8211; or &#x2013;, and might have a link which should not be damaged, I could fix the module. Johnuniq (talk) 06:25, 25 March 2017 (UTC)
@Johnuniq and Mr. Stradivarius: The easiest solution without messing with parsing pages in the module would probably be to add a tracking category in Infobox Chinese/Chinese for templates containing unexpected characters, run over all the pages using template with Joe's Null Bot, and replace all the XML entities before re-adding {{Tone superscript}}. It could potentially still be problematic if there are things like pronunciation templates though. Jc86035 (talk) Use {{re|Jc86035}}
to reply to me
06:43, 25 March 2017 (UTC)
Wouldn't it be easier to make the module apply <sup>...</sup> to a digit only if it's preceded by letters? – Uanfala (talk) 08:40, 25 March 2017 (UTC)
@Uanfala: The problem is that character entities in hexadecimal can contain letters a–f and x, which prevents that from working. Jc86035 (talk) Use {{re|Jc86035}}
to reply to me
09:53, 25 March 2017 (UTC)
I see. Maybe it can exclude strings starting with & and ending with ;, just as it will exclude ones enclosed in double square brackets? An alternative would be to use mw.text.decode to convert the html entities to the unescaped characters, but it will need checking whether any of them wouldn't disrupt the template that calls the module. – Uanfala (talk) 09:59, 25 March 2017 (UTC)
@Uanfala: I didn't realize that function existed. I don't think the template would be disrupted, since there shouldn't be a wide variety of characters in the input anyway, and vertical bars and such output by Scribunto can't be used to construct templates. Jc86035 (talk) Use {{re|Jc86035}}
to reply to me
10:31, 25 March 2017 (UTC)

function inside Lua

Hello folks, is there any chance putting a function inside this module, which will give me the opportunity to add languages with {{#invoke:Languages|getCode|language code}}? -- Vēnī‧vīdī‧scrīpsī [DM] 18:03, 27 March 2017 (UTC)

What can be wrong with the function get_wiki? I constantly get this error — "Lua error: bad argument #1 to 'gsub' (string expected, got table).". -- Vēnī‧vīdī‧scrīpsī [DM] 12:25, 29 March 2017 (UTC)
How are you calling that function? If like this:
{{#invoke:Wt/cu/PartOfSpeech|get_wiki|de}}
then the problem is in get_wiki(). You aren't getting the language code argument from the arguments table passed into the function from wiki text; instead, you are getting the arguments table and passing that to mw.text.trim() which is expecting a string, not an arguments table. See mw:Extension:Scribunto/Lua_reference_manual#Accessing parameters from wikitext for a more detailed description of how arguments work.
Trappist the monk (talk) 13:25, 29 March 2017 (UTC)
Trappist the monk, I can look at it, but will probably not understand it :(. -- Vēnī‧vīdī‧scrīpsī [DM] 13:52, 29 March 2017 (UTC)
I have tweaked the module so that you can call get_wiki() with {{#invoke:Wt/cu/PartOfSpeech|get_wiki|de}}
I changed the function call's argument name and added a line to extract the language code from the argument table. It apparently works, see: incubator:User talk:Trappist the monk. Something happens, though I'm not sure if the rendered result is correct.
Trappist the monk (talk) 14:16, 29 March 2017 (UTC)

Script request

I'm looking for a script that will look at a range of values, display the most recent three (or any other number to be defined) and then show the rest of the values in a collapsed list. The example I am looking at is {{

Infobox GB station}} and the usage statistics. These figures exist going back to 2002/3 (and a parallel set of interchange figures as well) so including them all gives a very long list. Ideally a script would look at the list, find the most recent three recorded, which are not necessarily the most up-to-date three, display those and then show the rest in a collapsed table. I know there are issues about the template needing an update to show the most recent figures first but if the base data was most recent first like {{UK railway station usage}} is this something that can be done? Nthep (talk
) 13:12, 12 April 2017 (UTC)

This is possible, but
WP:MOSCOLLAPSE is relevant in that case. --Izno (talk
) 13:51, 12 April 2017 (UTC)
@Izno and Nthep: Could this alternatively be done using Wikidata lookup (pending two property proposals)? It's probably better to put the data into WD first since then we don't need another Lua module containing the data. Jc86035 (talk) Use {{re|Jc86035}}
to reply to me
14:06, 12 April 2017 (UTC)
@Jc86035: Either there or the Data namespace on Commons. --Izno (talk) 14:09, 12 April 2017 (UTC)
Never been sure of the Data namespace at Commons since the advent of WD. Re
WP:MOSCOLLAPSE there doesn't seem to be too mcuh of an issue as the data is "purely supplementary, e.g. several past years of statistics in collapsed tables for comparison with a table of uncollapsed current stats". Nthep (talk
) 14:13, 12 April 2017 (UTC)
Data namespace came after WD, not before--it was recognized as a need because WD does a shit job at even modestly-sized data. --Izno (talk) 14:33, 12 April 2017 (UTC)
Shows how much out of tough I am. I can't even find it on Commons, any links? Nthep (talk) 16:10, 12 April 2017 (UTC)
I was under the impression that the Data: namespace on Commons was intended for data that could be used to generate graphs or annotate maps, etc. I can't find any interface that would allow the data to be imported into a Lua program running on enwiki, but I'd be happy to hear about one. @Nthep: some simple examples can be seen at c:Data:Sandbox/Yurik.tab and c:Data:Sandbox/Gabbg82/Orio.tab as well as more complex templates like c:Data:Templatedata/Graph:Lines.tab, if that's any help to you. (And before you ask, I don't know where the documentation is, either). Cheers --RexxS (talk) 19:19, 12 April 2017 (UTC)
Yurik can probably help more, but it looks like Lua access is possible now or was planned (ref mediawikiwiki:Extension:JsonConfig/Tabular#Usage). Or you can poke around over there to see if you can identify the Lua for accessing a data page (file?). --Izno (talk) 19:37, 12 April 2017 (UTC)
That was the proposed interface for Scribunto, but eventually it became as described in mw:Help:Tabular_Data#Usage. Note that the table returned is separated out into a schema and a data element, just as the json serialization. —TheDJ (talkcontribs) 20:04, 12 April 2017 (UTC)

@Nthep: The Wikidata property for patronage/ridership has been created, so I assume the data can now be imported into there using QuickStatements. I'm not sure how to use a qualifier for interchange traffic although has role (P2868) → interchange station (Q1147171) might work. Jc86035 (talk) Use {{re|Jc86035}}
to reply to me
07:14, 19 April 2017 (UTC)

Change module

Hello. I am a user in Greek Wikipedia.

1) w:el:Module:Επίσημηονομασίασεξένηγλώσσα These shows the P1448 property if the language is not Greek. But is showing only the first language. If there are shows of them, only shows the first one.

2) I want, near the result, to have language code. For example, "London (en)". The code must be link to wikidata item of the language if there is not an article to Greek Wikipedia. If there is an article of the language to Greek Wikipedia, to show link to that article. If it is too difficult is ok only to show the code. Maybe can link to w:el:ISO 639-1.

If the module works, then you must see the phrase "Επίσημη ονομασία: London (en)" or "Επίσημη ονομασία: London (en)" under the blue box [2].

Xaris333 (talk) 14:47, 18 April 2017 (UTC)

Please give an example of an article where more than one language would be returned, and show the exact wikitext that you would like for the result.
The wikitext above is Επίσημη ονομασία: London ([[English language|en]])
Perhaps cities are different, but I see that Germany (Q183) has 15 official names. Is there a reason that, for example, London (Q84) would not be expanded in time so that it might have 100 official names? Listing them would not be helpful?
For London, official name (P1448) is language = "en" and text = "London". How would "English language" be derived from "en"?
Regarding making a link, determining whether an article exists is an expensive operation and it adds an entry to "what links here". It may be better to have a built-in list of titles somewhere.
Regarding the idea of extracting Wikidata from various modules, I'm not sure it is a good idea. Wikidata is very quirky and it might be better to have a main module (Module:Wikidata or Module:Wd) which has the core functions to access data, then your module would call the intermediary. Johnuniq (talk) 03:50, 19 April 2017 (UTC)


@Johnuniq: Hello. official name (P1448) description: "official name of the subject in its official language(s)". So, is wrong to use this property to translate the name in many language. I can also use native label (P1705), is not a problem. Some regions have two official language so the name must be show in both language. Our main module shows all the values of a property (according to their rank of course). But this module, only shows the first one.
Yes, it is difficult. Is there a way just to show the language code? London (en)? I have a module that can only show the code (bun not in brackets) w:el:Module:Κωδικόςγλώσσας. I only wanted these two modules to be one.

Xaris333 (talk) 13:24, 19 April 2017 (UTC)

How to debug "The ID entered is unknown to the system. Please use a valid entity ID." errors

We just rolled out on Commons c:Module:Creator that mimics c:Template:Creator but can also fetch any field from Wikidata if needed. The issue I have is with few creator templates like c:Creator:Tomás Povedano that end up in Category:Pages with script errors. At this moment c:Creator:Tomás Povedano only shows "The ID entered is unknown to the system. Please use a valid entity ID." error, but the message like that disappeared from other pages without any edits. c:Creator:Tomás Povedano links to d:Q19675193 which is correct "entity ID". Any idea on how to debug this issue or what might cause it. phabricator:T143970 deals with this error but in context of how to detect bad "entity IDs" aka q-codes. --Jarekt (talk) 17:46, 23 April 2017 (UTC)

An example page is now at c:User:Jarekt/a--Jarekt (talk) 17:14, 24 April 2017 (UTC)

Include relative submodule?

Hi. Is there a way to include a submodule that is relative to the current module like require("Module:SomeName/sub") where SomeName is not fixed? I.e. is there a way to include /sub without the need to define Module:SomeName or is there a way to dynamically determine the current module's title Module:SomeName? thayts💬 21:33, 4 May 2017 (UTC)

Not tested exactly but:
function module_name.main(frame)
local some_data = mw.loadData (frame:getTitle() .. '/sub');
Something similar to this is used in Module:Citation/CS1 so that the module can mw.loadData() or require() live or sand box modules as required. See mw:Extension:Scribunto/Lua_reference_manual#frame:getTitle.
Trappist the monk (talk) 21:56, 4 May 2017 (UTC)
Hmm yeah, I've tried frame:getTitle() before, but that does not necessarily return the title of the calling module itself. For example, if the module is invoked in the examples section of its documentation then the returned value is actually Module:Documentation. thayts💬 06:56, 5 May 2017 (UTC)
@Thayts: frame:getTitle() is the best thing we have, as far as I'm aware. — Mr. Stradivarius ♪ talk ♪ 14:34, 5 May 2017 (UTC)
It seems like it depends on the context in which frame:getTitle() is called. If inside a function that received the frame object, then the current module's title seems to be returned. If outside a function call, like where require() is typically called, then it depends (also, I was using mw.getCurrentFrame():getTitle() there). I think I will have a look at mw.loadData(). Thank you both! thayts💬 17:49, 5 May 2017 (UTC)

And what if the module that is including the submodule is actually included through require() itself? I.e. require("Module:SomeName"), how does Module:SomeName know it was included by that name? There is no frame involved here and mw.getCurrentFrame():getTitle() certainly does not return Module:SomeName, so how could it construct Module:SomeName/sub? thayts💬 10:34, 6 May 2017 (UTC)

Found it, it's in the triple dot parameter ... passed to the module. thayts💬 18:21, 6 May 2017 (UTC)

Nested template calls

It's a FAQ, could not find the answer. Q: Can I make nested calls to an #invoking template?

{{OuterTemplate
|title=Bar
|{{InnerTemplate|a|A}}
|{{InnerTemplate|b|B}}
}}

(And does the answer apply for both template calls and direct #invoke|main calls?) -DePiep (talk) 11:15, 11 May 2017 (UTC)

like this?
Match the pattern and return everything that follows the initial digits:
{{#invoke:String|match|s=123{{snd}}456 |pattern=%d*(.*) |plain=false |nomatch=nomatch_output }}
 – 456
{{snd}} was called before the {{#invoke:}}. Which is to be expected.
Trappist the monk (talk) 12:38, 11 May 2017 (UTC)
Thanks. -DePiep (talk) 13:38, 11 May 2017 (UTC)

Newlines in Module:Navbar

Module:Navbar appears to contain :newline(); for no reason (after each of the square brackets in "[ v · t · e ]"), which might be causing a detected syntax error on the German Wikivoyage (discussion in English). Are they necessary and should they be replaced with spaces? (Pinging DerFussi.) Jc86035 (talk) Use {{re|Jc86035}}
to reply to me
16:05, 10 May 2017 (UTC)

The original Module:Navbar split from Module:Navbox added the newline, which was added when Navbar got Lua-fied in Module:Navbox. Toohool Do you remember/know why those newlines are there? I'll ping Dragons flight too but I doubt he'll be around to help soon. (We might just be able to remove them regardless whether they are causing the issue if they're not serving a purpose.) --Izno (talk) 16:30, 10 May 2017 (UTC)
I don't know why Dragons flight added those newlines. They were not present in the equivalent wikicode. Toohool (talk) 17:36, 10 May 2017 (UTC)
I have no useful recollection of why there might be newlines there. Dragons flight (talk) 11:39, 11 May 2017 (UTC)
I figured that would be the answer. Jc86035 Try removing them on de.wv and see if that resolves the error on the page in question. --Izno (talk) 12:34, 11 May 2017 (UTC)
@Izno: It seems to work on dewikivoyage. I've also added spaces. The odd thing is, in Special:ExpandTemplates (using this template), the display is slightly different to the normal output – the hlist spacing is slightly off (although maybe that's the site CSS). I think this was causing a problem in Safari (iOS); the square brackets would display on separate lines. Jc86035 (talk) Use {{re|Jc86035}}
to reply to me
12:57, 11 May 2017 (UTC)
Made an edit request. Jc86035 (talk) Use {{re|Jc86035}}
to reply to me
07:28, 13 May 2017 (UTC)

Unsubst for infoboxes

Is it possible to use

Infobox single}} and their auxiliary templates like {{Extra chronology}}.) Jc86035 (talk) Use {{re
|Jc86035}}
to reply to me
07:26, 13 May 2017 (UTC)

No, that's well beyond what Module:Unsubst does. I'd recommend that, if you try to make something to do what you want, you do it in a different module since Module:Unsubst is very widely used. Anomie 11:51, 13 May 2017 (UTC)
@Anomie: I've started a fork at Module:Unsubst-infobox. I don't understand the bracket in line 62; how would I remove the tracking category and the $N parameter from it? Jc86035 (talk) Use {{re|Jc86035}}
to reply to me
14:01, 13 May 2017 (UTC)
Like this? Anomie 14:41, 13 May 2017 (UTC)
@Anomie: Thanks. Jc86035 (talk) Use {{re|Jc86035}}
to reply to me
14:46, 13 May 2017 (UTC)

more issues

I've tried setting up {{Infobox song/sandbox}} with the new module, but the alias handling |$A= isn't working for some reason. Could anyone help with this? Thanks, Jc86035 (talk) Use {{re|Jc86035}}
to reply to me
05:49, 14 May 2017 (UTC)

(to test, take a random template from Template:Infobox song/doc, change the template title to subst:Infobox song/sandbox, and press the "show changes" button Jc86035 (talk) Use {{re|Jc86035}}
to reply to me
05:54, 14 May 2017 (UTC))

Problems

Could someone help me with Module:Unsubst-infobox, which I'm trying to fork from Module:Unsubst? I'm trying to get some of the new parameters in it to work but for some reason the input data gets lost somewhere. Maybe I'm using mw.text.split wrong. Jc86035 (talk) Use {{re|Jc86035}}
to reply to me
14:42, 15 May 2017 (UTC)

@Jc86035: I would be happy to look at the code but I can't take the time at the moment to work out the backstory. If you could provide an example of wikitext that might be previewed in a sandbox, and outline what is wrong with the result, I'll investigate. Johnuniq (talk) 23:33, 15 May 2017 (UTC)
@Johnuniq: The code
{{subst:Infobox song/sandbox
| Name      = Song
}}
should yield, per the current code of Template:Infobox song/sandbox,
{{Infobox song/sandbox
| name      = Song
| type      =
| writer    =
| composer  =
| lyricist  =
| written   =
| published =
| misc      =
}}
but currently produces
{{Infobox song/sandbox
| name          =
| cover         =
| cover_size    =
| alt           =
| border        =
| caption       =
| type          =
| artist        =
| album         =
| EP            =
| language      =
| English_title =
| writer        =
| composer      =
| lyricist      =
| written       =
| published     =
| genre         =
| recorded      =
| studio        =
| venue         =
| length        =
| producer      =
| released      =
| label         =
| format        =
| A-side        =
| B-side        =
| ISWC          =
| chronology    =
| prev_title    =
| prev_year     =
| next_title    =
| next_year     =
| prev          =
| prev_no       =
| next          =
| next_no       =
| tracks        =
| misc          =
}}
The smaller list of parameters (currently |$S3=) is supposed to replace the full list, and the value of parameter |Name= should be transferred to parameter |name= (lowercase) as defined in |$A=. Jc86035 (talk) Use {{re|Jc86035}}
to reply to me
05:35, 16 May 2017 (UTC)
@Jc86035: That is very complex and involves several things I am not familiar with. Primarily, I have no idea when mw.isSubsting returns true (does it return true if previewing something where subst is used?). My first thought was to stick the following just after the if that tests mw.isSubsting:
error('mw.isSubsting is true')
then see when the error is displayed. However, "what links here" for the module shows it is used in several articles. I added that to the module (without saving) and previewed the change on Antz. There was no error. I don't know what that means.
Is aliases[tmp[1]] = aliases[tmp[2]] correct? The RHS should be tmp[2].
I think I would need a complete sandboxed test system to go any further—an unused module and template, and something that called the template. Johnuniq (talk) 11:07, 16 May 2017 (UTC)
@Johnuniq: I don't think mw.isSubsting should be a problem, since it's straight from Module:Unsubst (2 million transclusions). Changing it to tmp[2] works for some of the aliases but not all of them (e.g. try showing changes for substituting the infobox of Waltzing Matilda, with title changed to "subst:Infobox song/sandbox"). Jc86035 (talk) Use {{re|Jc86035}}
to reply to me
11:36, 16 May 2017 (UTC)
@Johnuniq: Surprisingly enough, changing pairs() to iterate on the aliases table instead of the args table worked. I have no idea why. Jc86035 (talk) Use {{re|Jc86035}}
to reply to me
10:29, 17 May 2017 (UTC)
The new code seems good (and clearer). I skimmed the old version while looking at the module but never fully decoded that part because it was after the issue I found. Johnuniq (talk) 10:58, 17 May 2017 (UTC)
@Johnuniq: What could be causing the $S1–3 parameters not to work? I've tried changing the module to iterate over params instead of args, but it still doesn't work (try the example on this page). Jc86035 (talk) Use {{re|Jc86035}}
to reply to me
11:22, 17 May 2017 (UTC)
I won't be around much for the next couple of days. If you don't solve it, I'll have a look in under 24 hours but I would like some clarity on what you mean by trying the example. Are you referring to the three lines of wikitext above with Name = Song? Where would I paste it? Wouldn't it have to be ExpandTemplates to see the "should yield" or "currently produces" results? What would I look for to know (a) that it is currently not working, and (b) that it is working if I think of something? Johnuniq (talk) 11:47, 17 May 2017 (UTC)
@Johnuniq: Yes, the first code block from the top; anywhere (use "show changes"); ExpandTemplates would expand {{Infobox}} as well and doesn't work with subst added (since the module returns different output when not being substituted); if the changed wikitext matches the second code block above it would be working. Jc86035 (talk) Use {{re|Jc86035}}
to reply to me
12:41, 17 May 2017 (UTC)

@Jc86035: I fixed two problems in Module:Unsubst-infobox:

-- Changed
for k, v in ipairs( {frame.args['$S1'], frame.args['$S2'], frame.args['$S3']} ) do
-- to
for k = 1, 3 do
    local v = frame.args['$S' .. k]

-- Changed
if v ~= {} then
-- to
if next(v) then  -- if table v is not empty

In the first, ipairs stops at the first nil, so if there is no $S1 parameter, the original code would not test the other two parameters.

In the second, two different tables are never equal. Consider the following code:

t = {}
if t == {} then print('1: EMPTY') else print('1: NOT empty') end
if next(t) then print('2: NOT empty') else print('2: EMPTY') end

If run on a computer with Lua, the above would print:

1: NOT empty
2: EMPTY

There may be other issues, but that's all I have time for at the moment. If there is still a problem, please provide an example using $S1 (add it here if wanted) and outline what shows that it is wrong, and what the correct result would be. Johnuniq (talk) 10:38, 18 May 2017 (UTC)

@Johnuniq: The test now returns an infobox with no parameters, regardless of whether {{Infobox song/sandbox}} uses $S1 or $S3. I'm not sure why. {{Audio sample}}, which also uses the module (but with only $P and $E) works fine. Jc86035 (talk) Use {{re|Jc86035}}
to reply to me
11:17, 18 May 2017 (UTC)
It seems that if there are ≥4 parameters then every parameter is returned, but if there are ≤3 parameters then no parameters are returned (at least if any of the $S parameters are used). Jc86035 (talk) Use {{re|Jc86035}}
to reply to me
11:37, 18 May 2017 (UTC)
I might be able to find more problems later but you would need to address what I said just above. As mentioned, I don't have the time to work out the backstory and indeed I don't want to understand another complex template and its parameters. So far I have just read the code and identified three bugs, but for more I would need to know what to look for. Johnuniq (talk) 11:40, 18 May 2017 (UTC)
@Johnuniq: I've added another test to your sandbox. Hope it helps. Jc86035 (talk) Use {{re|Jc86035}}
to reply to me
12:07, 18 May 2017 (UTC)
@Jc86035: I was about to have another look but I see you edited Module:Unsubst-infobox. Using table.remove with a standard ipairs won't work as expected. I'll have a look later. Johnuniq (talk) 07:30, 19 May 2017 (UTC)
@Johnuniq: I tried putting table.remove directly in the ipairs at first (in the sandbox), but as you mentioned it didn't work so I changed it to remove the values afterwards in reverse order. I think that works. Jc86035 (talk) Use {{re|Jc86035}}
to reply to me
09:07, 19 May 2017 (UTC)
Sorry, I misread what was happening. I patched User:Jc86035/sandbox and had intended to revert myself. Revert if you're trying something, but I put an experiment at Module:Sandbox/Johnuniq/ip (see its talk) which is inconsistent with other tests I've done. Something mysterious is happening with $S1 that I will have to leave for now, and try again later. Johnuniq (talk) 12:16, 19 May 2017 (UTC)
@Jc86035: I knew it would be an obvious problem! It is ipairs( sets ) which should be pairs because each item in the set is of the form 'example' = true so ipairs will get nothing. I'm hopelessly confused about $P and $S and more so I'm not going to fix it at the moment. However, I might look at working out what should be done if you don't fix it first. Johnuniq (talk) 00:41, 20 May 2017 (UTC)
@Johnuniq: Don't think so. sets is a table containing three other tables, so ipairs should work for it. Maybe it's better to just scrap the thing and use parser functions to add parameters to $E instead. Jc86035 (talk) Use {{re|Jc86035}}
to reply to me
04:39, 20 May 2017 (UTC)
@Jc86035: Sorry I reported the problem wrongly (there was half an hour between finding and reporting). It's not ipairs(sets), it is ipairs(params) in line 147. Bear in mind that I still do not understand the parameters or what is going on, but at line 147 params might be a numbered table (in which case ipairs would work as expected), but it might be a set. That would occur if the code at line 129 executed params = v which would replace params with sets[1] (for the case where $S1 has a relevant value). Johnuniq (talk) 06:42, 20 May 2017 (UTC)

@Johnuniq: So params = v was the problem. It should be fixed now. Jc86035 (talk) Use {{re|Jc86035}}
to reply to me
07:52, 20 May 2017 (UTC)