Module:Common
Module:Common
Shared stateless helper functions, which can be loaded in other Lua modules via:
local common = require("Module:Common")
Usage
This module also exposes a few permanent utility entry points.
Get URL-safe version of a given string
MessageBundle keys are built from a slugified (URL-safe) version of a string. Use this to check the exact slug a given input will produce.
If no value is specified, it defaults to the current page's title:
{{#invoke:Common|checkSlug}}
A specific string can also be provided instead:
{{#invoke:Common|checkSlug|Terrarium of Muad'Dib}}
Get an auto-localised string from a MessageBundle
Retrieves a string for a given key from a specified MessageBundle. It auto-switches to the language that the viewer's page is currently on, and falls back to the English source if no translation exists for the current language.
{{#invoke:Common|localise|Vehicles|sandbike-name}}
Optionally, set link=yes to wrap the result as a stable link to the English page name, e.g. [[Wildlife of Arrakis|Fauna von Arrakis]]:
{{#invoke:Common|localise|DLC|wildlife-of-arrakis-name|link=yes}}
Parameters
checkSlug
- 1 (optional)
- string
- The string to generate a slug for.
- If omitted, defaults to the current page's title.
localise
- 1
- string
- The name of the MessageBundle to look up (without the "MessageBundle:" prefix).
- 2
- string
- The key to retrieve from the MessageBundle.
- link (optional)
- boolean
- If true, wraps the result as
[[English|Translation]]instead of just plain text. - Defaults to false.
local p = {}
local tmb = require("mw.ext.translate.messageBundle")
-- ---------- String ----------
-- trims any whitespace on the edges
function p.trim(s)
return mw.text.trim(s or "")
end
-- converts string to lowercase and trims any whitespace on the edges
function p.lowerTrim(s)
return mw.ustring.lower(p.trim(s))
end
-- checks whether a string represents a truthy value; case-insensitive
function p.isTruthy(s)
s = p.lowerTrim(s)
return s == "true" or s == "yes" or s == "1"
end
-- checks whether a list of strings contains a specified token; case-insensitive
function p.listContains(list, token)
token = p.lowerTrim(token)
for _, item in ipairs(list) do
if p.lowerTrim(item) == token then return true end
end
return false
end
-- splits a "Bundle:slug" source token into its parts
function p.parseSourceToken(token)
return token:match("^([^:]+):(.+)$")
end
-- returns a URL-friendly version of a specified string
function p.slugify(name)
local s = mw.text.decode(name)
s = mw.ustring.lower(s)
s = mw.ustring.gsub(s, "[^%w%s_]", "")
s = mw.ustring.gsub(s, "%s+", "_")
s = mw.ustring.gsub(s, "_+", "_")
s = mw.ustring.gsub(s, "^_+", ""):gsub("_+$", "")
return s
end
-- returns a display-ready error message, standardised for use across all modules
-- any number of extra args can be specified to be encoded and substituted into msg
function p.error(msg, ...)
if select("#", ...) > 0 then
local args = {...}
for i = 1, #args do args[i] = mw.text.encode(tostring(args[i])) end
msg = string.format(msg, unpack(args))
end
return '<strong class="error">⚠ ' .. msg .. '</strong>'
end
-- ---------- Translation ----------
-- retrieves a string value associated with a specified key from a specified MessageBundle
-- optionally wraps the result as [[<ENGLISH>|<TRANSLATION>]] if `link` is true
function p.translate(bundleName, key, lang, link, silent)
local bundlePage = "MessageBundle:" .. bundleName
-- if `lang` is nil, tmb.new() automatically attempts to grab a string of the invoking page's language
-- if a translation does not exist, it falls back to the English source
local ok, mb = pcall(tmb.new, bundlePage, lang)
if not ok then
if silent then return nil end
return p.error("MessageBundle:%s not found.", bundleName)
end
local msg = mb:t(key)
if not msg then
if silent then return nil end
return p.error("Missing key '%s' in MessageBundle:%s.", key, bundleName)
end
local translated = msg:plain()
if not link then return translated end
local _, mbEn = pcall(tmb.new, bundlePage, "en")
return string.format("[[%s|%s]]", mbEn:t(key):plain(), translated)
end
-- ---------- Rendering ----------
-- creates a standard sortable, collapsible wikitable with a count-prefixed caption
-- returns the mw.html table object, ready for header/rows to be added
function p.newSortableTable(count, bundleName, labelKey)
local table_ = mw.html.create("table")
:addClass("wikitable sortable mw-collapsible")
:css("text-align", "center")
table_:tag("caption"):addClass("scalable-text")
:wikitext(string.format("%dx %s ", count, p.translate(bundleName, labelKey, nil, true)))
return table_
end
-- ---------- Interface ----------
-- wrapper for p.slugify(), exposed as an entry point to check URL-friendly versions of specified strings
-- this is specifically intended to help in cases where it may not be clear what IDs to use in MessageBundles
function p.checkSlug(frame)
local input = frame.args[1]
if not input or input == "" then input = mw.title.getCurrentTitle().rootText end
return p.slugify(input)
end
-- wrapper for p.translate(), exposed as an entry point for wikitext pages to grab strings from MessageBundles directly
function p.localise(frame)
local args = frame.args
return p.translate(args[1], args[2], nil, p.isTruthy(args.link))
end
return p