Page MenuHomePhabricator

Support insertion of Scribunto Lua modules using Visual Editor
Open, Needs TriagePublic

Description

It's quite possible that this was already requested, but I cannot find such a task.

Visual Editor has an Insert -> Template function. I couldn't find a way to insert an invocation of a Scribunto Lua module the same way, even though modules are quite similar to templates.

I guess that the reason for this is that there is an assumption that modules are usually not used directly in articles, but are only used internally in templates. I suspect, however, that this assumption is not quite true: searching the main space of the English Wikipedia for insource:#invoke finds quite a lot of direct module invocations.

It appears to be possible to edit a module that was included just like editing a template. Its name will appear as "#invoke:Module name". I couldn't find a way to insert a new one, however, and it should be possible.

I actually have very little experience with developing Scribunto Lua modules, so I might be very wrong about this, but as far as I can see, a module invocation is not very different from a template, except the #invoke: part, and also passing the Lua function name as the first parameter. So I guess that the dialog for inserting a function can look almost the same as the one for inserting a template. Perhaps it can even be the same dialog, an if the user asks for a module, it will add another input box that asks for the function name.

Another issue is that I'm not aware of a way for a Lua module to list the parameters in a structured way that is similar to TemplateData, and perhaps it should be added.

Event Timeline

Let me say that I'm your mirror: I know Scribunto but I really don't know Visual Editor :^)

AFAIK direct invocations through the {{#invoke}} parser function are not appreciated because it's somehow more appreciated to have an additional abstraction layer between templates and their implementations.

E.g. you can use a template {{Foo}} built using simple parsing functions or tomorrow it will be converted to Lua or vice versa, or using Brainfuck (who knows future implementations!).

I think that this is the reason behind the preference of the standard templates syntax as frontend entry point for Lua modules.

Yeah, so that's what I don't get: //Why/ is it "somehow more appreciated to have an additional abstraction layer"? Is it actually good?

For the users perspective the [[Template:Banana]] can have a certain behaviour, but if today that behaviour is implemented using simple parsing functions and magic keywords, tomorrow we can implement that behaviour thanks to a sometime more efficient Lua module, and we can do it without changing a bit for the user perspective: people can continue to write {{Banana}} without the need to migrate to {{#invoke:Banana|main}}, because that invocation can be safetly leaved hidden under the hood of {{Foo}} to do not scare users.

I understand why users prefer simplicity, backward compatibility, and well known syntax at the cost of a "dummy" template page.

Having said that, I'm with you that the {{#invoke:Banana|main}} syntax is not that scaring. IMVHO it's the community that sometime scares this shy and kind feature :^)

For an existing template one can say that people are accustomed to using it. Bit if a new module is created, is there a reason to wrap it in a template? Isn't it superfluous?

That's a smart question. For more background about this topic let me say that whenever a template may be implemented by a Lua module, a Lua module can provide much functions and so can provide the implementations for multiple templates. A Lua documentation is always much more complicate than a template one.

That's a smart question. For more background about this topic let me say that whenever a template may be implemented by a Lua module, a Lua module can provide much functions and so can provide the implementations for multiple templates.

It's true and probably common, but it's also possible to write a module with several functions and call the functions directly. Is one approach better than the other?

A Lua documentation is always much more complicate than a template one.

Why is it more complicated? From the vantage point of the article editor it's pretty much the same.

In T205197#4609777, @Amire80 wrote:
Why is it more complicated? From the vantage point of the article editor it's pretty much the same.

One example is better than thousand words :)

https://en.wikipedia.org/wiki/Module:Wikidata

The whole module has long documentation, yes. Some templates have long documentation, too. However, TemplateData is not the whole documentation, but just a brief description of each parameter.

Oh, sorry me. I'm not proficient with English Wikipedia examples. Look at this instead:

https://it.wikipedia.org/wiki/Modulo:Wikidata

E.g. the function _getProperty(args, rawTable) vs getProperty(frame).

What I'm trying to say is that a Lua module does not provide only a single function available through invoke, but can provide multiple functions available through invoke together with more low-level functions that can't simply be invoked from wikitext because are made to be called from other Lua modules. Morover, this distinction actually does not exist formally, and it's made only with good faith naming conventions (e.g. that _ as prefix).

So it's not that easy for a Lua module to have a TemplateData-like documentation, because:

  1. A single Lua module provides multiple functions
  2. Not all of these functions are anyway callable from the wikitext context

This is why a Lua module documentation (sometimes) is very complicated over a single template documentation. The template documentation always describes only its "parameters", while a module needs to document every exposed function with every parameter type (boolean, string, table, etc.) and return type, etc. for both calls from others Lua modules or from wikitext invocations.

There should probably be a way to comprehensively document all Lua functions, including internal ones, that are not directly invoked by pages or templates. Something like JSDuck for JavaScript or Doxygen for PHP.

But for this task I'm talking about something like TemlateData, which exists primarily (though not exclusively) to allow easy insertion of templates into pages using VE.

searching the main space of the English Wikipedia for insource:#invoke finds quite a lot of direct module invocations.

Link: https://en.wikipedia.org/w/index.php?search=insource%3Ainvoke+insource%3A%2F%5C%23invoke%2F&title=Special%3ASearch&profile=advanced&fulltext=1&ns0=1

At a glance, a lot of them seem to be for Module:Chart. There doesn't seem to be any particular reason that module is used without a wrapper template.

So it's not that easy for a Lua module to have a TemplateData-like documentation, because:

  1. A single Lua module provides multiple functions
  2. Not all of these functions are anyway callable from the wikitext context

#1 is a real issue. VE would probably really want a TemplateData-like documentation for each wikitext-callable function rather than for the module itself.

#2 doesn't seem like an issue to me, just don't add TemplateData for those functions. They can still be documented in other ways.

There should probably be a way to comprehensively document all Lua functions, including internal ones, that are not directly invoked by pages or templates. Something like JSDuck for JavaScript or Doxygen for PHP.

Note we decided to encourage wikitext /doc subpages rather than luadoc or other inline documentation because edits to inline documentation will cause every page using the module to be reparsed.

I think it's a good practice to put a template layer between the module API and the the article, it brings much flexibility. Not adding it in the VE default layout might actually be presented as a "feature not a bug". Not bothering article writers with too much technical complexity is great.

Thus said, it might be fine to add an optional entry for module invocation in VE, or making it visible by default only in template edition. I don't think I ever tried to edit a template with VE, and actually don't even know if it's currently possible.

I guess that the reason for this is that there is an assumption that modules are usually not used directly in articles, but are only used internally in templates. I suspect, however, that this assumption is not quite true: searching the main space of the English Wikipedia for insource:#invoke finds quite a lot of direct module invocations.

But how can we be sure that supporting this behaviour is not supporting a really, really, truly a bad practice? Why those 12,000 usages (searching by insource:/\#invoke/) weren’t done by template? Is there some proper reasoning for this or was it done without thinking? That’s the question that should be asked first, and only then this proposal can be considered.

As far as I see it, there are no real reasons to support insertion of modules via visual editor, since most of those usages can be explained either by Hanlon’s razor or by substituting a template somewhere.

I guess that the reason for this is that there is an assumption that modules are usually not used directly in articles, but are only used internally in templates. I suspect, however, that this assumption is not quite true: searching the main space of the English Wikipedia for insource:#invoke finds quite a lot of direct module invocations.

But how can we be sure that supporting this behaviour is not supporting a really, really, truly a bad practice?

But why is it a bad practice? Till now I haven't heard a single really good explanation of why is it bad, or why using a template that does nothing but call a module is good.

Other than one more word, #invoke:, calling a Lua module is not more complicated than calling a template.

But why is it a bad practice? Till now I haven't heard a single really good explanation of why is it bad, or why using a template that does nothing but call a module is good.

Other than one more word, #invoke:, calling a Lua module is not more complicated than calling a template.

Because modules practically always represent abstractions and templates are ‘front-facing’ interfaces that can be improved on top of those abstractions as much as users would like. Using #invoke in a page is like substituting an infobox (which some people, believe it or not, do, but we shouldn’t support this just because it is done).

But why is it a bad practice? Till now I haven't heard a single really good explanation of why is it bad, or why using a template that does nothing but call a module is good.

The explanation that convinced me is that it allows the implementation to be changed to something else than a Lua module. For example, if a "native" parser function to do whatever the template/module does is implemented in the future, changing a template to use it is easier than changing a Lua module.

But why is it a bad practice? Till now I haven't heard a single really good explanation of why is it bad, or why using a template that does nothing but call a module is good.

Other than one more word, #invoke:, calling a Lua module is not more complicated than calling a template.

Because modules practically always represent abstractions and templates are ‘front-facing’ interfaces that can be improved on top of those abstractions as much as users would like.

Modules can also be improved as much as users would like. Many modules are easier to improve than many templates. Templates are not inherently more front-facing than modules.

Using #invoke in a page is like substituting an infobox

No, it's not at all like substituting an infobox.

But why is it a bad practice? Till now I haven't heard a single really good explanation of why is it bad, or why using a template that does nothing but call a module is good.

The explanation that convinced me is that it allows the implementation to be changed to something else than a Lua module. For example, if a "native" parser function to do whatever the template/module does is implemented in the future, changing a template to use it is easier than changing a Lua module.

How is it easier?

Was it ever actually done with a template? The only example I can think is {{!}}, although there may be more. {{!}} was lucky to have the same short name in many wikis, so it didn't need a bot to replace it in the wiki syntax.

Rewriting some templates (or even many templates!) as cross-project magic words is probably a good idea, but I don't see how it will be significantly easier to replace them in the wiki syntax than to replace module invocations. At the worst case, one can run a bot that removes #invoke, which doesn't sound like a big deal. Bots do much weirder things.

Rewriting some templates (or even many templates!) as cross-project magic words is probably a good idea, but I don't see how it will be significantly easier to replace them in the wiki syntax than to replace module invocations. At the worst case, one can run a bot that removes #invoke, which doesn't sound like a big deal. Bots do much weirder things.

You would not need to do replacements in all pages. The pages would still use the same syntax, {{foo|…}}, and only Template:Foo would have to be changed from {{#invoke:foo|{{{1}}}}} to {{#foo:{{{1}}}}}, or something. However, if you used {{#invoke:foo|…}} directly in pages, they would have to be edited by a bot. (Well, technically you could change the module to call the parser function, too…)

I have no personal opinion on this, just trying to explain the rationale I've heard.