<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.tachyony.co.uk/w/index.php?action=history&amp;feed=atom&amp;title=Wikipedia%3AGuide_to_Scribbling</id>
	<title>Wikipedia:Guide to Scribbling - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.tachyony.co.uk/w/index.php?action=history&amp;feed=atom&amp;title=Wikipedia%3AGuide_to_Scribbling"/>
	<link rel="alternate" type="text/html" href="https://wiki.tachyony.co.uk/w/index.php?title=Wikipedia:Guide_to_Scribbling&amp;action=history"/>
	<updated>2026-05-15T02:36:10Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.35.5</generator>
	<entry>
		<id>https://wiki.tachyony.co.uk/w/index.php?title=Wikipedia:Guide_to_Scribbling&amp;diff=1689&amp;oldid=prev</id>
		<title>Tachyony: Imported page</title>
		<link rel="alternate" type="text/html" href="https://wiki.tachyony.co.uk/w/index.php?title=Wikipedia:Guide_to_Scribbling&amp;diff=1689&amp;oldid=prev"/>
		<updated>2021-12-06T12:27:21Z</updated>

		<summary type="html">&lt;p&gt;Imported page&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{Nutshell|Scribbling is a way to create complex templates and is more robust than [[Help:Magic_words#Parser_functions|parser functions]]. A scribbled template consists of only &amp;lt;nowiki&amp;gt;{{#invoke:Name1|Name2}}&amp;lt;/nowiki&amp;gt;, which invokes the script at Module:Name1, where the code is written. To get started, refer to [[Module:Example]]. Try the module by using [[Template:Basic scribbling example]] in your sandbox.}}&lt;br /&gt;
[[File:Wikipe-tan the Library of Babel.png|thumb|right|&amp;quot;Shh!  I&amp;#039;m reading about how to Scribble templates.&amp;quot;]]&lt;br /&gt;
{{toc right}}&lt;br /&gt;
This is the Guide to &amp;#039;&amp;#039;&amp;#039;Scribbling&amp;#039;&amp;#039;&amp;#039;.  Scribbling, also known as Luafication, is the act of writing a template, or converting a template, so that it uses [[:mw:Extension:Scribunto|the Scribunto extension]] to [[MediaWiki]]. The Scribunto extension{{efn|The name &amp;quot;Scribunto&amp;quot; is Latin.  &amp;quot;[[wikt:scribunto#Latin|scribunto]]&amp;quot; is third person plural [[future tense|future]] [[active voice|active]] [[imperative mood|imperative]] of &amp;quot;[[wikt:scribunto#Latin|scribere]]&amp;quot; and means &amp;quot;they shall write&amp;quot;.  &amp;quot;[[wikt:scribble#English|scribble]]&amp;quot; is of course an English word derived from that Latin word, via [[Mediaeval Latin]] &amp;quot;[[wikt:scribillare#Latin|scribillare]]&amp;quot;.{{sfn|MW|2003a|p=1116}}}} was developed by [[User:Tim Starling|Tim Starling]] and [[User:VasilievVV|Victor Vasiliev]], and allows for embedding scripting languages in MediaWiki. Currently the only supported scripting language is [[Lua (programming language)|Lua]]. This Guide aims to give you a broad overview of Scribbling, and pointers to further information in various places.&lt;br /&gt;
&lt;br /&gt;
Scribbled templates come in two parts: the template itself and one or more back-end &amp;#039;&amp;#039;modules&amp;#039;&amp;#039; &amp;amp;mdash; in the &amp;lt;code&amp;gt;Module:&amp;lt;/code&amp;gt; namespace &amp;amp;mdash; that contain programs that are run on [[m:Wikimedia servers|the wiki servers]] to generate the wikitext that the template expands to.  The template invokes a function within a module using a new [[m:Help:Parser function|parser function]] named &amp;lt;syntaxhighlight lang=html5 inline&amp;gt;{{#invoke:}}&amp;lt;/syntaxhighlight&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The idea of Scribbling is to improve template processing performance.  Scribbling eliminates any need for &amp;#039;&amp;#039;template parser function programming&amp;#039;&amp;#039; using parser functions such as {{tlc|&amp;amp;#35;if}}, {{tlc|&amp;amp;#35;ifeq}}, {{tlc|&amp;amp;#35;switch}} and {{tlc|&amp;amp;#35;expr}}. All of this is instead done in the module, in a language that was actually designed to be a programming language, rather than a template system onto which was bolted various extensions over time to try to make it into a programming language.{{efn|For an idea of what &amp;quot;bolted-on&amp;quot; connotes when it comes to software design, see the &amp;#039;&amp;#039;[[The Flintstones|Flintstones]]&amp;#039;&amp;#039; cartoons where the rack of ribs from the Drive-Thru is so heavy that it causes the Flintstones&amp;#039; car to fall on its side.}}  Scribbling also eliminates any need for templates to expand to further templates and potentially hit the [[m:Help:Expansion depth|expansion depth limit]].  A fully Scribbled template should never need to [[Project:transclusion|transclude]] other templates.{{efn|It may need, until such time as the whole of the specified API for Scribunto is available to modules, to transclude &amp;#039;&amp;#039;[[m:Help:magic words|magic words]]&amp;#039;&amp;#039;.  See [[#Tips and tricks|the tips and tricks section]].  Magic words are not templates, however.}}&lt;br /&gt;
&lt;br /&gt;
== Lua ==&lt;br /&gt;
{{further|Lua (programming language)|Help:Lua for beginners|{{FULLPAGENAME}}/Programmers&amp;#039; Quick start Guide to Lua}}&lt;br /&gt;
The language in which modules are written is Lua.  Unlike the template parser function system, Lua was actually designed not only to be a proper programming language, but also to be a programming language that is suitable for what is known as &amp;#039;&amp;#039;embedded scripting&amp;#039;&amp;#039;.  Modules in MediaWiki are an example of embedded scripts.  There are several embedded scripting languages that could have been used, including [[REXX]] and [[tcl]]; and indeed the original aim of Scribunto was to make available a choice of such languages.  At the moment, however, only Lua is available.&lt;br /&gt;
&lt;br /&gt;
The official reference manual for Lua is {{harvnb|Ierusalimschy|de Figueiredo|Celes|2006}}.  It&amp;#039;s a reference, not a tutorial.  Consult it if you want to know the syntax or semantics for something.  For a tutorial, see either {{harvnb|Ierusalimschy|2006}}  ({{harvnb|Ierusalimschy|2003}} is also available, although it is of course out of date.) or {{harvnb|Jung|Brown|2007}}.  The downsides to these books are that quite a lot of the things that they tell you about have no bearing upon using Lua in MediaWiki modules.  You don&amp;#039;t need to know how to install Lua and how to integrate its interpreter into a program or run it standalone.  The MediaWiki developers have done all of that.  Similarly, a lot of the Lua library functions are, for security, not available in modules.  (For example, it&amp;#039;s not possible to do file I/O or to make operating system calls in MediaWiki modules.)  So, much of what these books explain about Lua standard library functions and variables that come with the language is either irrelevant or untrue here.&lt;br /&gt;
&lt;br /&gt;
The original API specification &amp;amp;mdash; the Lua standard library functions and variables that are supposed to be available in modules &amp;amp;mdash; is given at [[MW:Extension:Scribunto/API specification]].  However, even that is untrue.  What you&amp;#039;ll &amp;#039;&amp;#039;actually&amp;#039;&amp;#039; have available is documented in [[MW:Extension:Scribunto/Lua reference manual]], which is a cut down version of the 1st Edition Lua manual that has been edited down and modified by Tim Starling to bring it more into line with the reality of Scribbling.  Again, though, this is a reference manual, not a tutorial.&lt;br /&gt;
&lt;br /&gt;
The things in Lua that you will mostly be concerned with, writing Scribbled templates, are &amp;#039;&amp;#039;tables&amp;#039;&amp;#039;, &amp;#039;&amp;#039;strings&amp;#039;&amp;#039; &amp;#039;&amp;#039;numbers&amp;#039;&amp;#039;, &amp;#039;&amp;#039;booleans&amp;#039;&amp;#039;, &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;nil&amp;lt;/syntaxhighlight&amp;gt;, &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;if … then … else … end&amp;lt;/syntaxhighlight&amp;gt;, &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;while … do … end&amp;lt;/syntaxhighlight&amp;gt;, &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;for … in … do … end&amp;lt;/syntaxhighlight&amp;gt; (generated &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;for&amp;lt;/syntaxhighlight&amp;gt;), &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;for … do … end&amp;lt;/syntaxhighlight&amp;gt; (numerical &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;for&amp;lt;/syntaxhighlight&amp;gt;), &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;repeat … until&amp;lt;/syntaxhighlight&amp;gt;, &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;function … end&amp;lt;/syntaxhighlight&amp;gt;, &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;local&amp;lt;/syntaxhighlight&amp;gt;, &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;return&amp;lt;/syntaxhighlight&amp;gt;, &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;break&amp;lt;/syntaxhighlight&amp;gt;, expressions and the various operators (including &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;#&amp;lt;/syntaxhighlight&amp;gt;, &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;..&amp;lt;/syntaxhighlight&amp;gt;, the arithmetic operators &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;+&amp;lt;/syntaxhighlight&amp;gt;, &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;-&amp;lt;/syntaxhighlight&amp;gt;, &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;*&amp;lt;/syntaxhighlight&amp;gt;, &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;/&amp;lt;/syntaxhighlight&amp;gt;, &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;^&amp;lt;/syntaxhighlight&amp;gt;, and &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;%&amp;lt;/syntaxhighlight&amp;gt;), and the &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;string&amp;lt;/syntaxhighlight&amp;gt;, &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;math&amp;lt;/syntaxhighlight&amp;gt;, and &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;mw&amp;lt;/syntaxhighlight&amp;gt; global tables (i.e. libraries).&lt;br /&gt;
&lt;br /&gt;
== Template structure ==&lt;br /&gt;
This is simple.  Your template comprises one expansion of &amp;lt;syntaxhighlight lang=html5 inline&amp;gt;{{#invoke:}}&amp;lt;/syntaxhighlight&amp;gt; in the usual case.  Here is {{tl|Harvard citation}}, for example:&lt;br /&gt;
{{#tag:syntaxhighlight|{{#invoke:Page|getContent|Template:Harvard citation|as=raw}}|lang=html5}}&lt;br /&gt;
If you find yourself wanting to use other templates within your template, or to use template parser functions, or indeed anything at all other than &amp;lt;syntaxhighlight lang=html5 inline&amp;gt;{{#invoke:}}&amp;lt;/syntaxhighlight&amp;gt; and possibly some [[m:Help:Variable|variable]]s as its arguments, &amp;#039;&amp;#039;then you are using the wrong approach&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
== Module basics ==&lt;br /&gt;
=== Overall structure ===&lt;br /&gt;
Let&amp;#039;s consider a hypothetical module, [[Module:Population]].  (See [[Module:Population clocks]] for a similar, but more complex, module.)  It can be structured in one of two ways:&lt;br /&gt;
==== A named local table ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=Lua line&amp;gt;&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
function p.India(frame)&lt;br /&gt;
    return &amp;quot;1,21,01,93,422 people at (nominally) 2011-03-01 00:00:00 +0530&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==== An unnamed table generated on the fly ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=Lua line&amp;gt;&lt;br /&gt;
return {&lt;br /&gt;
    India = function(frame)&lt;br /&gt;
        return &amp;quot;1,21,01,93,422 people at (nominally) 2011-03-01 00:00:00 +0530&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Execution====&lt;br /&gt;
The execution of a module by &amp;lt;syntaxhighlight lang=html5 inline&amp;gt;{{#invoke:}}&amp;lt;/syntaxhighlight&amp;gt; is actually twofold:&lt;br /&gt;
# The module is loaded and the entire script is run.  This loads up any additional modules that the module needs (using the &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;require()&amp;lt;/syntaxhighlight&amp;gt; function), builds the (invocable) functions that the module will provide to templates, and returns a table of them.&lt;br /&gt;
# The function named in &amp;lt;syntaxhighlight lang=html5 inline&amp;gt;{{#invoke:}}&amp;lt;/syntaxhighlight&amp;gt; is picked out of the table built in phase 1 and called, with the arguments supplied to the template &amp;#039;&amp;#039;and&amp;#039;&amp;#039; the arguments supplied to &amp;lt;syntaxhighlight lang=html5 inline&amp;gt;{{#invoke:}}&amp;lt;/syntaxhighlight&amp;gt; (more on which [[#Receiving template arguments|later]]).&lt;br /&gt;
&lt;br /&gt;
The first Lua script  does phase 1 fairly explicitly.  It creates a &amp;#039;&amp;#039;local variable&amp;#039;&amp;#039; named &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; on line 1, initialized to a table; builds and adds a function to it (lines 3&amp;amp;ndash;5), by giving the function the name &amp;lt;code&amp;gt;India&amp;lt;/code&amp;gt; in the table named by &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; (&amp;lt;syntaxhighlight lang=Lua inline&amp;gt;function p.India&amp;lt;/syntaxhighlight&amp;gt; being the same as saying &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;p[&amp;quot;India&amp;quot;] = function&amp;lt;/syntaxhighlight&amp;gt;{{efn|The inventors of the language call this [[syntactic sugar]].{{sfn|Ierusalimschy|de Figueiredo|Celes|2011|loc=&amp;amp;sect;DATA}}}}); and then returns (on line 7) the table as the last line of the script.  To expand such a script with more (invocable) functions, one adds them between the &amp;lt;syntaxhighlight lang=html5 inline&amp;gt;local&amp;lt;/syntaxhighlight&amp;gt; statement at the top and the &amp;lt;syntaxhighlight lang=html5 inline&amp;gt;return&amp;lt;/syntaxhighlight&amp;gt; statement at the bottom.  (Non-invocable &amp;#039;&amp;#039;local&amp;#039;&amp;#039; functions can be added &amp;#039;&amp;#039;before&amp;#039;&amp;#039; the &amp;lt;syntaxhighlight lang=html5 inline&amp;gt;local&amp;lt;/syntaxhighlight&amp;gt; statement.)  The local variable doesn&amp;#039;t have to be named &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;.  It could be named any valid Lua variable name that you like. &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; is simply conventional for this purpose, and is also the name that you can use to test the script in the debug console of the Module editor.&lt;br /&gt;
&lt;br /&gt;
The second Lua script does the same thing, but more &amp;quot;idiomatically&amp;quot;.  Instead of creating a named variable as a table, it creates an anonymous table on the fly, in the middle of the &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;return&amp;lt;/syntaxhighlight&amp;gt; statement, which is the only (executed during the first phase) statement in the script.  The &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;India = function(frame) … end&amp;lt;/syntaxhighlight&amp;gt; on lines 2&amp;amp;ndash;4 creates an (also anonymous) function and inserts it into the table under the name &amp;lt;code&amp;gt;India&amp;lt;/code&amp;gt;.  To expand such a script with more (invocable) functions, one adds them as further fields in the table.  (Non-invocable &amp;#039;&amp;#039;local&amp;#039;&amp;#039; functions can, again, be added &amp;#039;&amp;#039;before&amp;#039;&amp;#039; the &amp;lt;syntaxhighlight lang=html5 inline&amp;gt;return&amp;lt;/syntaxhighlight&amp;gt; statement.)&lt;br /&gt;
&lt;br /&gt;
In both cases, the template code that one writes is &amp;lt;syntaxhighlight lang=html5 inline&amp;gt;{{#invoke:Population|India}}&amp;lt;/syntaxhighlight&amp;gt; to &amp;#039;&amp;#039;invoke&amp;#039;&amp;#039; the function named &amp;lt;code&amp;gt;India&amp;lt;/code&amp;gt; from the module [[Module:Population]].  Also note that &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;function&amp;lt;/syntaxhighlight&amp;gt; &amp;#039;&amp;#039;builds&amp;#039;&amp;#039; a function, as an object, to be called.  It doesn&amp;#039;t &amp;#039;&amp;#039;declare&amp;#039;&amp;#039; it, as you might be used to from other programming languages, and the function isn&amp;#039;t executed until it &amp;#039;&amp;#039;is&amp;#039;&amp;#039; called.&lt;br /&gt;
&lt;br /&gt;
One can do more complex things than this, of course.  For example:  One can declare other local variables in addition to &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, to hold tables of data (such as lists of Language or country names), that the module uses.  But this is the &amp;#039;&amp;#039;basic&amp;#039;&amp;#039; structure of a module.  You make a table full of stuff, and return it.&lt;br /&gt;
&lt;br /&gt;
=== Receiving template arguments ===&lt;br /&gt;
An ordinary function in Lua can take an (effectively) arbitrary number of arguments.  Witness this function from [[Module:Wikitext]] that can be called with anywhere between zero and three arguments: &amp;lt;syntaxhighlight lang=Lua&amp;gt;function z.oxfordlist(args,separator,ampersand)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Functions called by &amp;lt;syntaxhighlight lang=html5 inline&amp;gt;{{#invoke:}}&amp;lt;/syntaxhighlight&amp;gt; are special.  They expect to be passed exactly one argument, a table that is called a &amp;#039;&amp;#039;frame&amp;#039;&amp;#039; (and so is conventionally given the parameter name &amp;lt;code&amp;gt;frame&amp;lt;/code&amp;gt; in the parameter list of the function).  It&amp;#039;s called a &amp;#039;&amp;#039;frame&amp;#039;&amp;#039; because, unfortunately, the developers chose to name it for their convenience.  It&amp;#039;s named after an internal structure within the code of MediaWiki itself, which it &amp;#039;&amp;#039;sort of&amp;#039;&amp;#039; represents.{{efn|In MediaWiki proper, there are more than two frames.}}&lt;br /&gt;
&lt;br /&gt;
This frame has a (sub-)table within it, named &amp;lt;code&amp;gt;args&amp;lt;/code&amp;gt;.  It also has a means for accessing its &amp;#039;&amp;#039;parent frame&amp;#039;&amp;#039; (again, named after a thing in MediaWiki).  The parent frame &amp;#039;&amp;#039;also&amp;#039;&amp;#039; has a (sub-)table within it, also named &amp;lt;code&amp;gt;args&amp;lt;/code&amp;gt;.&lt;br /&gt;
* The arguments in the (child, one supposes) frame &amp;amp;mdash; i.e. the value of the &amp;lt;code&amp;gt;frame&amp;lt;/code&amp;gt; parameter to the function &amp;amp;mdash; are the arguments passed to &amp;lt;syntaxhighlight lang=html5 inline&amp;gt;{{#invoke:}}&amp;lt;/syntaxhighlight&amp;gt; &amp;#039;&amp;#039;within the wikitext of your template&amp;#039;&amp;#039;.  So, for example, if you were to write &amp;lt;syntaxhighlight lang=html5 inline&amp;gt;{{#invoke:Population|India|a|b|class=&amp;quot;popdata&amp;quot;}}&amp;lt;/syntaxhighlight&amp;gt; in your template then the arguments sub-table of the child frame would be (as written in Lua form) &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;{ &amp;quot;a&amp;quot;, &amp;quot;b&amp;quot;, class=&amp;quot;popdata&amp;quot; }&amp;lt;/syntaxhighlight&amp;gt;.&lt;br /&gt;
* The arguments in the parent frame are the arguments &amp;#039;&amp;#039;passed to your template when it was transcluded&amp;#039;&amp;#039;.  So, for example, were the user of your template to write &amp;lt;syntaxhighlight lang=html5 inline&amp;gt;{{Population of India|c|d|language=Hindi}}&amp;lt;/syntaxhighlight&amp;gt; then the arguments sub-table of the parent frame would be (as written in Lua form) &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;{ &amp;quot;c&amp;quot;, &amp;quot;d&amp;quot;, language=&amp;quot;Hindi&amp;quot; }&amp;lt;/syntaxhighlight&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
A handy programmers&amp;#039; idiom that you can use, to make this all a bit easier, is to have local variables named (say) &amp;lt;code&amp;gt;config&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;args&amp;lt;/code&amp;gt; in your function, that point to these two argument tables.  See this, from [[Module:WikidataCheck]]:&amp;lt;syntaxhighlight lang=Lua&amp;gt;&lt;br /&gt;
function p.wikidatacheck(frame)&lt;br /&gt;
	local pframe = frame:getParent()&lt;br /&gt;
	local config = frame.args -- the arguments passed BY the template, in the wikitext of the template itself&lt;br /&gt;
	local args = pframe.args -- the arguments passed TO the template, in the wikitext that transcludes the template&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Everything in &amp;lt;code&amp;gt;config&amp;lt;/code&amp;gt; is thus an argument that &amp;#039;&amp;#039;you&amp;#039;&amp;#039; have specified, in your template, that you can reference with code such as &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;config[1]&amp;lt;/syntaxhighlight&amp;gt; and &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;config[&amp;quot;class&amp;quot;]&amp;lt;/syntaxhighlight&amp;gt;.  These will be things that tell your module function its &amp;quot;configuration&amp;quot; (e.g. a CSS class name that can vary according to what template is used).&lt;br /&gt;
&lt;br /&gt;
Everything in &amp;lt;code&amp;gt;args&amp;lt;/code&amp;gt; is thus an argument that &amp;#039;&amp;#039;the user of the template&amp;#039;&amp;#039; has specified, where it was transcluded, that you can reference with code such as &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;args[1]&amp;lt;/syntaxhighlight&amp;gt; and &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;args[&amp;quot;language&amp;quot;]&amp;lt;/syntaxhighlight&amp;gt;.  These will be the normal template arguments, as documented on your template&amp;#039;s &amp;lt;code&amp;gt;/doc&amp;lt;/code&amp;gt; page.&lt;br /&gt;
&lt;br /&gt;
See {{tl|other places}} and {{tl|other ships}} for two templates that both do &amp;lt;syntaxhighlight lang=html5 inline&amp;gt;{{#invoke:Other uses|otherX|x}}&amp;lt;/syntaxhighlight&amp;gt; but do so with different arguments in place of the &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;, thereby obtaining different results from one single common Lua function.&lt;br /&gt;
&lt;br /&gt;
For both sets of arguments, the name and value of the argument are exactly as in the wikitext, except that leading and trailing whitespace in named parameters is discounted.  This has an effect on your code if you decide to support or employ transclusion/invocation argument names that aren&amp;#039;t valid Lua variable names.  You cannot use the &amp;quot;dot&amp;quot; form of table lookup in such cases.  For instance: &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;args.author-first&amp;lt;/syntaxhighlight&amp;gt; is, as you can see from the syntax colourization here, not a reference to an &amp;lt;code&amp;gt;|author-first=&amp;lt;/code&amp;gt; argument, but a reference to an &amp;lt;code&amp;gt;|author=&amp;lt;/code&amp;gt; argument and a &amp;lt;code&amp;gt;first&amp;lt;/code&amp;gt; variable with the subtraction operator in the middle.  To access such an argument, use the &amp;quot;square bracket&amp;quot; form of table lookup: &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;args[&amp;quot;author-first&amp;quot;]&amp;lt;/syntaxhighlight&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Named arguments are indexed in the &amp;lt;code&amp;gt;args&amp;lt;/code&amp;gt; table by their name strings, of course.  Positional arguments (whether as the result of an explicit &amp;lt;code&amp;gt;1=&amp;lt;/code&amp;gt; or otherwise) are indexed in the &amp;lt;code&amp;gt;args&amp;lt;/code&amp;gt; tables by number, not by string.  &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;args[1]&amp;lt;/syntaxhighlight&amp;gt; is not the same as &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;args[&amp;quot;1&amp;quot;]&amp;lt;/syntaxhighlight&amp;gt;, and the latter is effectively unsettable from wikitext.  &lt;br /&gt;
&lt;br /&gt;
Finally, note that Lua modules can differentiate between arguments that have been used in the wikitext and simply set to an empty string, and arguments that aren&amp;#039;t in the wikitext at all.  The latter don&amp;#039;t exist in the &amp;lt;code&amp;gt;args&amp;lt;/code&amp;gt; table, and any attempt to index them will evaluate to &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;nil&amp;lt;/syntaxhighlight&amp;gt;.  Whereas the former &amp;#039;&amp;#039;do&amp;#039;&amp;#039; exist in the table and evaluate to an empty string, &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;&amp;quot;&amp;quot;&amp;lt;/syntaxhighlight&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Errors ===&lt;br /&gt;
Let&amp;#039;s get one thing out of the way right at the start: &amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color:red; bgcolor:white;&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;Script error&amp;#039;&amp;#039;&amp;#039;&amp;lt;/span&amp;gt; is a hyperlink.  You can put the mouse pointer on it and click.&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
We&amp;#039;ve become so conditioned by our (non-Scribbled) templates putting out error messages in red that we think that the Scribunto &amp;quot;Script error&amp;quot; error message is nothing but more of the same.  It isn&amp;#039;t.  If you have [[JavaScript]] enabled in your WWW browser, it will pop up a window giving the details of the error, a call backtrace, and even hyperlinks that will take you to the location of the code where the error happened in the relevant module.&lt;br /&gt;
&lt;br /&gt;
You can cause an error to happen by calling the &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;error()&amp;lt;/syntaxhighlight&amp;gt; function.  &lt;br /&gt;
== Tips and tricks ==&lt;br /&gt;
=== Arguments tables are &amp;quot;special&amp;quot;.  ===&lt;br /&gt;
For reasons that are out of the scope of this Guide,{{efn|If you want to know, go and read about how MediaWiki, in part due to the burden laid upon it by the old templates-conditionally-transcluding-templates system, does [[lazy evaluation]] of template arguments.}} the &amp;lt;code&amp;gt;args&amp;lt;/code&amp;gt; sub-table of a frame is not quite like an ordinary table.  It starts out empty, and it is populated with arguments as and when you execute code that looks for them.{{efn|Don&amp;#039;t be surprised, therefore, if you find a call backtrace showing a call to some other module in what you thought was an ordinary template argument reference.  That will be because expansion of that argument involved expanding another Scribbled template.}}  (It&amp;#039;s possible to make tables that work like this in a Lua program, using things called &amp;#039;&amp;#039;metatables&amp;#039;&amp;#039;.  That, too, is outwith the scope of this Guide.)&lt;br /&gt;
&lt;br /&gt;
An unfortunate side-effect of this is that some of the normal Lua table operators don&amp;#039;t work on an &amp;lt;code&amp;gt;args&amp;lt;/code&amp;gt; table. The length operator, &amp;lt;code&amp;gt;#&amp;lt;/code&amp;gt;, will not work, and neither will the functions in Lua&amp;#039;s &amp;lt;code&amp;gt;table&amp;lt;/code&amp;gt; library. These only work with standard tables, and fail when presented with the special &amp;lt;code&amp;gt;args&amp;lt;/code&amp;gt; table. However, the &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;pairs()&amp;lt;/syntaxhighlight&amp;gt; and &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;ipairs()&amp;lt;/syntaxhighlight&amp;gt; functions will both work, as code to make their use possible has been added by the developers.&lt;br /&gt;
&lt;br /&gt;
=== Copy table contents into local variables. ===&lt;br /&gt;
A name in Lua is either an access of a local variable or a table lookup.{{sfn|Ierusalimschy|de Figueiredo|Celes|2011|loc=&amp;amp;sect;EVAL AND ENVIRONMENTS}}  &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;math.floor&amp;lt;/syntaxhighlight&amp;gt; is a table lookup (of the string &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;&amp;quot;floor&amp;quot;&amp;lt;/syntaxhighlight&amp;gt;) in the (global) &amp;lt;code&amp;gt;math&amp;lt;/code&amp;gt; table, for example.  Table lookups are slower, at runtime, than local variable lookups.  Table lookups in tables such as the &amp;lt;code&amp;gt;args&amp;lt;/code&amp;gt; table with [[#Arguments tables are &amp;quot;special&amp;quot;.|its &amp;quot;specialness&amp;quot;]] are a &amp;#039;&amp;#039;lot&amp;#039;&amp;#039; slower.&lt;br /&gt;
&lt;br /&gt;
A function in Lua can have up to 250 local variables.{{sfn|Ierusalimschy|2008|p=17}}  So make liberal use of them:&lt;br /&gt;
* If you call &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;math.floor&amp;lt;/syntaxhighlight&amp;gt; many times, copy it into a local variable and use that instead:{{sfn|Ierusalimschy|2008|p=17}}&amp;lt;syntaxhighlight lang=Lua&amp;gt;local floor = math.floor&lt;br /&gt;
local a = floor((14 - date.mon) / 12)&lt;br /&gt;
local y = date.year + 4800 - a&lt;br /&gt;
local m = date.mon + 12 * a - 3&lt;br /&gt;
return date.day + floor((153 * m + 2) / 5) + 365 * y + floor(y / 4) - floor(y / 100) + floor(y / 400) - 2432046&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Don&amp;#039;t use &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;args.something&amp;lt;/syntaxhighlight&amp;gt; over and over.  Copy it into a local variable and use that:&amp;lt;syntaxhighlight lang=Lua&amp;gt;local Tab = args.tab&amp;lt;/syntaxhighlight&amp;gt;(Even the &amp;lt;code&amp;gt;args&amp;lt;/code&amp;gt; variable itself is a way to avoid looking up &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;&amp;quot;args&amp;quot;&amp;lt;/syntaxhighlight&amp;gt; in the &amp;lt;code&amp;gt;frame&amp;lt;/code&amp;gt; table over and over.)&lt;br /&gt;
&lt;br /&gt;
When copying arguments into local variables there are two useful things that you can do along the way:&lt;br /&gt;
* The &amp;#039;&amp;#039;alternative names for the same argument&amp;#039;&amp;#039; trick.  If a template argument can go by different names &amp;amp;mdash; such as uppercase and lowercase forms, or different English spellings &amp;amp;mdash; then you can use Lua&amp;#039;s &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;or&amp;lt;/syntaxhighlight&amp;gt; operator to pick the highest priority name that is actually supplied:&amp;lt;syntaxhighlight lang=Lua&amp;gt;local Title = args.title or args.encyclopaedia or args.encyclopedia or args.dictionary&lt;br /&gt;
local ISBN = args.isbn13 or args.isbn or args.ISBN&amp;lt;/syntaxhighlight&amp;gt;This works for two reasons:&lt;br /&gt;
** &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;nil&amp;lt;/syntaxhighlight&amp;gt; is the same as &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;false&amp;lt;/syntaxhighlight&amp;gt; as far as &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;or&amp;lt;/syntaxhighlight&amp;gt; is concerned.&lt;br /&gt;
** Lua&amp;#039;s &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;or&amp;lt;/syntaxhighlight&amp;gt; operator has what are known as &amp;quot;shortcut&amp;quot; semantics.  If the left-hand operand evaluates to something that isn&amp;#039;t &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;false&amp;lt;/syntaxhighlight&amp;gt; or &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;nil&amp;lt;/syntaxhighlight&amp;gt;, it doesn&amp;#039;t bother even working out the value of the right-hand operand.  (So whilst that first example may at first glance look like it does four lookups, in the commonest case, where &amp;lt;code&amp;gt;|title=&amp;lt;/code&amp;gt; is used with the template, it in fact only actually does one.)&lt;br /&gt;
* The &amp;#039;&amp;#039;default to empty string&amp;#039;&amp;#039; trick.  Sometimes the fact that an omitted template argument is &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;nil&amp;lt;/syntaxhighlight&amp;gt; is useful.  Other times, however, it isn&amp;#039;t, and you want the behaviour of missing arguments being empty strings.  A simple &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;or &amp;quot;&amp;quot;&amp;lt;/syntaxhighlight&amp;gt; at the end of an expression suffices:&amp;lt;syntaxhighlight lang=Lua&amp;gt;local ID = args.id or args.ID or args[1] or &amp;quot;&amp;quot;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Don&amp;#039;t expand templates, even though you can. ===&lt;br /&gt;
If local variables are cheap and table lookups are expensive, then template expansion is way above your price bracket.&lt;br /&gt;
&lt;br /&gt;
Avoid &amp;lt;syntaxhighlight lang=Lua inline&amp;gt;frame:preprocess()&amp;lt;/syntaxhighlight&amp;gt; like the plague.  Nested template expansion using MediaWiki&amp;#039;s preprocessor is what we&amp;#039;re trying to get away from, after all.  Most things that you&amp;#039;d do with that are done more simply, more quickly, and more maintainably, with simple Lua functions.&lt;br /&gt;
&lt;br /&gt;
Similarly, avoid things like using [[w:Template:ISO 639 name aze]] (&amp;#039;&amp;#039;[[Wikipedia:Templates_for_discussion/Log/2020_August_14#ISO_639_name_from_code_templates|deleted August 2020]]&amp;#039;&amp;#039;) to store what is effectively an entry in a database.  Reading it would be a nested parser call with concomitant database queries, all to map a string onto another string.  Put a simple straightforward data table in your module, like the ones in [[Module:Language]].&lt;br /&gt;
&lt;br /&gt;
== Footnotes ==&lt;br /&gt;
{{notelist|50em}}&lt;br /&gt;
== References ==&lt;br /&gt;
=== Cross-references ===&lt;br /&gt;
{{reflist|30em}}&lt;br /&gt;
=== Citations ===&lt;br /&gt;
{{refbegin}}&lt;br /&gt;
* {{cite dictionary|ref={{harvid|MW|2003a}}|dictionary=Merriam-Webster&amp;#039;s Collegiate Dictionary|entry=scribble|page=1116|edition=11th|publisher=Merriam-Webster|year=2003|isbn=9780877798095|title=Merriam-Webster&amp;#039;s Collegiate Dictionary: Eleventh Edition}}&lt;br /&gt;
* {{cite journal|title=Passing a Language through the Eye of a Needle|journal=Queue|publisher=Association for Computing Machinery|first1=Roberto|last1=Ierusalimschy|first2=Luiz Henrique|last2=de Figueiredo|first3=Waldemar|last3=Celes|date=12 May 2011|volume=9|issue=5|url=http://queue.acm.org/detail.cfm?id=1983083|id=ACM 1542-7730/11/0500}}&lt;br /&gt;
* {{cite book|title=Lua Programming Gems|editor3-first=Roberto|editor-last3=Ierusalimschy|editor-first1=Luiz Henrique|editor-last1=de Figueiredo|editor2-first=Waldemar|editor-last2=Celes|publisher=Lua.org| date=December 2008 |isbn=978-85-903798-4-3|chapter=Lua Performance Tips|first=Roberto|last=Ierusalimschy|chapter-url=http://lua.org./gems/sample.pdf}}&lt;br /&gt;
{{refend}}&lt;br /&gt;
&lt;br /&gt;
== Further reading ==&lt;br /&gt;
=== Lua ===&lt;br /&gt;
{{refbegin|indent=y}}&lt;br /&gt;
* {{cite book|title=Lua 5.1 Reference Manual|url=http://lua.org./manual/5.1/|author-first1=Roberto|author-last1=Ierusalimschy|author-first2=Luiz Henrique|author-last2=de Figueiredo|author3-first=Waldemar|author3-last=Celes|publisher=Lua.org| date=August 2006 |isbn= 85-903798-3-3}}&lt;br /&gt;
* {{cite book|title=Programming in Lua|edition=Second|author-first=Roberto|author-last=Ierusalimschy|language=English|publisher=Lua.org| date=March 2006 |isbn=9788590379829}}&lt;br /&gt;
* {{cite book|title=Programming in Lua|first=Roberto|last=Ierusalimschy|publisher=Lua.org| date=December 2003 |isbn=85-903798-1-7|url=http://lua.org./pil/#1ed|edition=First|language=English}}&lt;br /&gt;
* {{cite book|title=Beginning Lua Programming|first1=Kurt|last1=Jung|author2-first=Aaron|author2-last=Brown|isbn=978-0-470-06917-2| date=February 2007 |publisher=Wrox}}&lt;br /&gt;
{{refend|indent=y}}&lt;br /&gt;
&lt;br /&gt;
{{Wikipedia technical help|collapsed}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Wikipedia modules]]&lt;/div&gt;</summary>
		<author><name>Tachyony</name></author>
	</entry>
</feed>