Wiktionary:Scribunto/Converting templates

Many editors have some understanding of templates, and have built up a repertoire of "coding idioms". But as Scribunto is only new, we don't yet have a good set of established practices for Lua. This page is an attempt to gather up our experiences with converting templates to Lua, by explaining how to conceptually "translate" certain common practices.

Using libraries and modules from within Lua
If your code needs to use a function or table from another module or a built-in library, you can import it with the lua function. This function returns the value that the imported module or library itself returns (that is, the table of functions), which you must then store in a variable to use it later. Libraries that are part of Scribunto can be imported directly (except for the "mw" library, which is always available), but to import a module that is in the Module: namespace on Wiktionary, you have to include the Module: prefix in the lua call. For example:

Expanding wiki code
Lua scripts are much faster to run than template code. They are also more flexible and have more possibilities than templates. This means that it's best to try to delegate as much of the work to the module, and leave the template to do as little as possible. The template, ideally, would act as nothing more than "glue" between the wiki and Scribunto. Nevertheless, it may sometimes be desirable to transclude a template or a magic word. Scribunto provides two functions that allow you to access "wikispace" from within a module:  and.

The main use of this is to allow you to convert templates to Scribunto without having to convert all the templates it uses first. However, expanding wiki code is slow; much slower than just writing Lua code. So this should not be done if it's at all possible. If you find that a Scribunto module needs to use a template, then you could consider passing the result of that template to the invocation as a parameter. Or better yet, convert that template to a Scribunto module itself!

Page names and other magic words
The Scribunto library includes a collection of functions that are geared specifically towards wiki usage, and are intended to replace magic words such as. Here is an overview of some of the more important ones that are available, with their magic word equivalents:

Keep in mind that if you need to access lua multiple times, it's probably a good idea to store it in a variable the first time, and then re-use that variable for any subsequent uses. When you need to check whether a page is in a particular namespace, you can use lua instead, which is probably faster.

Ifexist
Among the parser functions that are available in templates is, which allows you to check whether a page exists or not. Lua has an equivalent that is a bit different, but also more flexible: lua.

Just like, the function  is considered an "expensive function". This means that there is a limit to how many times it and other expensive functions can be used altogether on a page; this limit is 500 as of February 2013. Like its template-code counterpart, it should therefore be used sparingly.

Empty parameters
In templates, you can use  to indicate that you want to use the parameter named   if it was given in the template call, or the string lua if it was not. In Lua you use the following equivalent (assuming you stored the arguments in the variable lua):

This will set the variable lua to whatever was passed to the template, but if the parameter was not passed at all it is set to lua by default. Of course, if you want to use an empty string as the default, just use lua instead.

Often, you want to use the same behavior if the parameter was missing as if it was blank; for example, in wikitext you might write. In Lua, you would write:

As a special case, if you want your default to be used whenever a parameter is missing or blank, you can write:

which sets lua to the equivalent of.

Conditionals, switches and the ternary operator
Template parser functions are functional and value-based, in that they evaluate expressions which result in a value (text) to return as a result, and do not store anything. Lua, however, is imperative: it is based on statements (commands) that are executed one at a time, and it allows you to store values in variables. Lua also has expressions, but while in wikitext everything is an expression (has a value), in Lua not everything is.

Unfortunately, Lua has no exact equivalent to a wikitext expression like. In Lua, the only true if-then-else construct is a statement, not an expression, so it does not return a value and cannot be embedded in a larger expression. However, there are a number of expression-level constructs, detailed in the "TernaryOperator" article on the lua-users wiki, that can approximate the effect of an if-then-else construct. One of the most popular is this notation:

This works because if the condition is true, it will (because of the lua) then evaluate the lua, and if not, it will evaluate lua. Unlike in templates and in Lua if-statements, the lua is required, because if it's left out, when the condition is lua, the expression as a whole evaluates literally to lua, which will trigger an error if you then use that result within a larger expression (because you can't concatenate lua to a string, for example). This method code will also break down if lua is either lua or, because lua and lua both evaluate to lua, so the lua will be used. You can avoid that by changing the condition around so that the then and else values are swapped (lua can be lua or lua).

For example, consider, where the second parameter specifies the entry to link to, and the third specifies the word to be displayed — but where the third parameter is optional, and if it's missing or blank, we want to display the name of the entry (i.e., the second parameter). In wikitext, we might write. In Lua, that could be expressed this way:

However, it might be clearer to take advantage of the fact that Lua variables, unlike template parameters, are mutable; so, we can write this instead:

You can also mimic a expression in this way, although there may be better ways to do that.