Guidelines:Modules: Difference between revisions

From Zelda Wiki, the Zelda encyclopedia
Jump to navigation Jump to search
No edit summary
(Undid revision 781463 by HylianKing (Talk))
Tags: Replaced Undo
Line 2: Line 2:
{{Big|Overview|3}}<br>
{{Big|Overview|3}}<br>


'''Modules''' are {{Wp|Lua (programming language)|Lua}} scripts for making [[Help:Templates|templates]] using a full-fledged programming language. You can ask questions about Zelda Wiki modules in the <code>#modules</code> [{{Discord}} Discord] channel.
'''Modules''' are {{Wp|Lua (programming language)|Lua}} scripts for making [[Help:Templates|templates]] using a full-fledged programming language.


==Getting Started==
==Overview==
In order to contribute to modules, you'll need to learn basic programming in Lua. You'll also need to know the specifics of Lua scripting on MediaWiki.
<!-- 00110011 01100100 00100000 01101101 01101111 01100100 01100101 01101100 00100000 01101111 01100110 00100000 01100001 00100000 01110100 01100101 01100001 01110000 01101111 01110100 -->
 
===Lua===
====Beginners====
====Developers====
If you already have some programming experience in other languages, note the following particularities of Lua.
 
{| class="wikitable"
! Particularities
! Further reading
|-
| <code>table</code>s are the only built-in object type. Any use of the term "array" actually refers to a table with integer keys.
 
The language offers prototype-based inheritance through '''metatables'''.
|
* [https://www.lua.org/pil/2.5.html Tables]
* [https://www.lua.org/pil/2.5.html Metatables and Metamethods]
|-
| Generally tables are 1-indexed as opposed to 0-indexed.
<syntaxhighlight lang="lua">
local tbl = {"foo"}
tbl[1]
> "foo"
</syntaxhighlight>
|
* [https://www.lua.org/pil/11.1.html Arrays]
|-
|
* The <code>ipairs</code> iterator is for <u>integer</u> key-value pairs in a table.
* The <code>pairs</code> iterator is for <u>all</u> key-value pairs, integer or otherwise.
|
* [https://www.lua.org/pil/4.3.5.html Generic <code>for</code>]
* [https://www.lua.org/pil/4.3.4.html Numeric <code>for</code>]
|-
| The length operator for a table is <code>#</code>.
 
<code>#</code> replaces the <code>table.getn</code> seen in the online version of ''Programming in Lua'', which is for Lua 5.0. <code>getn</code> won't work here as the wiki is on Lua 5.1 (at the time of writing).
 
<code>table.setn</code> was also deprecated and is unusable in 5.1. Unfortunately, the alternative <code>__len</code> field is only available in Lua 5.2.
|
|-
| Tables, <code>nil</code>, and the <code>#</code> operator don't interact the way similar constructs do in other languages.
<syntaxhighlight lang="lua">
#{ nil, nil, "foo" }
> 3
 
local tbl = {}
tbl[3] = "foo"
#tbl
> 0
 
tbl[1] = "bar"
#tbl
> 1
 
tbl[2] = "baz"
#tbl
> 3
</syntaxhighlight>
|
|}
 
===Scribunto===
:''For a broader, more in-depth guide, see [[gphelp:Extension:Scribunto|Gamepedia Help Wiki]].''
:''See also the full {{Mediawiki|Extension:Scribunto/Lua reference manual|Scribunto/Lua reference manual}}.''
'''Scribunto''' is the name of the extension that enables modules. It is the term used for concepts that are Lua-related but specific to MediaWiki.
 
The Lua on you see on MediaWiki is almost the same as standard Lua except for {{Mediawiki|Lua reference manual#Differences from standard Lua|some changes}} to library functions and packages. The main difference is in how Lua scripts are invoked.
 
====<code>#invoke</code>====
The <code>#invoke</code> {{Mediawiki|Help:Extension:ParserFunctions|parser function}} is what bridges the gap between templates and module scripts.{{Note|It is possible to invoke a module from any page, but it is almost always best to wrap the invocation in a template.}} For example, the {{Mediawiki|Transclusion|transcluded}} content of [[Template:Figurine]] is as follows:
<pre>
{{#invoke:Figurine|Main}}
</pre>
 
This invokes [[Module:Figurine]], which looks be something like:
 
<syntaxhighlight lang="lua">
local p = {}
local h = {}
local utilsGame = require("Module:UtilsGame")
...
 
function p.Main(frame)
    local args = frame:getParent().args
    local result = h.getFigurine(args[1], args[2])
    return result
end
 
function h.getFigurine(game, name)
...
end
 
return p
</syntaxhighlight>
 
A page can invoke any function that is a field on the module's '''export table'''. The export table is the <code>table</code> object returned by the module, which is always named <code>p</code> by convention. In this case, <code>Main</code> is the only function in the export table.
 
====<code>args</code>====
Functions called via <code>#invoke</code> are passed a {{Mediawiki|Extension:Scribunto/Lua reference manual#Frame object|Frame object}}. <code>frame.args</code> is a <code>table</code> of the arguments to <code>#invoke</code>—there are none in the above example. However, <code>frame:getParent().args</code> represents the ''template'' arguments. For example, if a page has <code><nowiki>{{Figurine|TMC|Minish Ezlo}}</nowiki></code>, then <code>frame:getParent().args[1]</code> evaluates to the string <code>TMC</code> in that invocation.
 
The <code>#</code> operator and most other table functions don't work on <code>frame.args</code>.
 
====<code>mw</code>====
Scribunto adds several libraries that are pre-loaded on all modules as the <code>mw</code> object. The following libraries are of note, in addition to the {{Mediawiki|Extension:Scribunto/Lua reference manual#Base functions|base functions}}:
 
{| class="wikitable"
! Library
! Usage example
|-
|<code>{{Mediawiki|Extension:Scribunto/Lua reference manual#Text library|mw.text}}</code>
|[[Module:List]]
|-
|<code>{{Mediawiki|Extension:Scribunto/Lua reference manual#Title library|mw.title}}</code>
|[[Module:Subpage List]]
|-
|<code>{{Mediawiki|Extension:Scribunto/Lua reference manual#HTML library|mw.html}}</code>
|[[Module:Infobox2]]
|}
 
====<code>require</code>====
A module can import another module and use its exported functions. This is done with the <code>require</code> function, as shown in the above example with [[Module:UtilsGame]].
 
===Utility Modules===
A utility module is a library-type module meant to be used by other modules, rather than being invoked by a template. Most template-facing modules use at least one of these:
* [[Module:UtilsGame]]
* [[Module:UtilsMarkup]]
* [[Module:UtilsTable]]
 
A complete list of utility modules can be found [https://zelda.gamepedia.com/Special:PrefixIndex?prefix=Utils&namespace=828 here].
 
====Higher-Order Functions====
In utility modules such as [[Module:UtilsTable]], you'll often see functions like these:
<syntaxhighlight lang="lua">
utilsTable.isEqual({})({})
> true
</syntaxhighlight>
 
You might've expected the usual function syntax <code>utilsTable.isEqual({}, {})</code> instead. The above is an example of a '''higher-order function'''—a function that returns a function. The function call above is shorthand for:
<syntaxhighlight lang="lua">
local isEmpty = utilsTable.isEqual({})
isEmpty({})
> true
</syntaxhighlight>
 
Functions are written this way for increased reusability. They are often composed with the other type of higher-order function—one that accepts a function as an argument:
<syntaxhighlight lang="lua">
local isEmpty = utilsTable.isEqual({})
local notEmpty = utilsFunction.negate(isEmpty)
local magicWords = utilsTable.filter(notEmpty)({ {}, {}, {"Kooloo"}, {"Limpah"} })
utilsTable.flatten(magicWords)
> { "Kooloo", "Limpah" }
</syntaxhighlight>
 
==Exercise==
 
{{Notes}}


{{Guidelines Nav}}
{{Guidelines Nav}}

Revision as of 21:19, 15 March 2020

Overview

Modules are Lua scripts for making templates using a full-fledged programming language.

Overview