Module:Translations
This is the documentation for Module:Translations, the translations-box renderer for the Yezur wiki. It is not called directly: Template:Translations invokes it with {{#invoke:Translations|render}} and the module reads the parameters given to that template. One box covers one English sense and lists the words the world's languages use for it, grouped by macro-family; boxes sit under a ====Translations==== heading following that sense's definitions, inside the English section of a Dictionary entry. Worked examples are at Template:Translations/testcases.
Parameters
| Parameter | Purpose |
|---|---|
gloss |
The sense being translated, shown in italics after Translations and an em dash in the box heading. Required: a headword with several senses carries one box per sense, and the gloss is what keeps them apart. When it is omitted the heading reads no gloss given in the error style instead.
|
| CODE | A registry code from Module:Languages used as the parameter name — YAQ-HE, YBS-PJ, YCQ-BE — with that language's word for the sense as the value. Any number may be given. A single value may hold several synonyms separated by commas, each of which is linked separately.
|
Every named parameter other than gloss is read as a language code; codes are matched case-insensitively. Parameters with an empty value are skipped, as are positional parameters. A gloss given on its own still renders the heading and an otherwise empty box; the module returns nothing at all when it is given neither a gloss nor any language parameter.
Grouping and order
Each word is linked to its Dictionary entry through Module:Languages, which anchors the link to the language's section heading and prefixes an asterisk for reconstructed languages — the star comes from the registry, not from the wikitext. Group headings are the registry's family field; known codes carrying no family are gathered under Isolates.
Rows are sorted by the second letter of the code, which is the family, then by the third, which is the era (P proto, Q ancient, R medieval, S modern, so alphabetical order is also chronological), then by language name, then by the code itself. The second letter likewise picks the colour class, tfam- followed by that letter. Colours and layout come from Template:Translations/styles.css, which the module loads through TemplateStyles; it defines tfam-A to tfam-E for the five families and tfam-X for the isolate codes.
A code the registry does not know is not silently dropped. Its words are left unlinked and printed after all the family groups as unrecognized code CODE: word in red, so that a typo or a language missing from the registry shows on the page.
The box is display-only: it stores nothing and is hand-curated per sense, in the same way as the family Members tables.
-- Module:Translations — the translations box for English lemma sections.
-- Backs Template:Translations. Collects, for ONE English sense, the words the
-- world's languages use for it, and renders them grouped by macro-family
-- (per the `family` field of Module:Languages; languages with no family are
-- gathered under "Isolates").
--
-- Called with |gloss= (the sense being translated — REQUIRED, so that a page
-- with several senses carries several boxes, one per sense) plus any number
-- of |<CODE>=word parameters, e.g. |YBS-PJ=tuku. A value may hold several
-- synonyms separated by commas; each is linked to its Dictionary entry,
-- starred automatically for reconstructed languages. Unknown codes render
-- visibly as errors rather than being dropped.
--
-- Display-only by design: no Cargo. The box is hand-curated per sense, like
-- the family Members tables (see the Cargo ruling of 2026-07-30).
local Languages = require('Module:Languages')
local p = {}
local ISOLATES = "Isolates" -- display bucket for family-less codes
function p.render(frame)
local args = frame:getParent().args
local gloss = mw.text.trim(args.gloss or "")
-- collect rows: one per language code given (named params only)
local rows = {}
for k, v in pairs(args) do
v = mw.text.trim(v or "")
if type(k) == "string" and k ~= "gloss" and v ~= "" then
local code = k
local l = Languages._get(code)
local words = {}
for w in mw.text.gsplit(v, ",") do
w = mw.text.trim(w)
if w ~= "" then
if l then
table.insert(words, Languages._build_link(w, l))
else
table.insert(words, w)
end
end
end
table.insert(rows, {
code = code,
name = l and l.name or code,
family = l and (l.family or ISOLATES) or nil,
-- 2nd code letter = family, 3rd = era (P proto < Q ancient
-- < R medieval < S modern — alphabetical IS chronological);
-- the family letter also picks the colour class.
famkey = code:sub(2, 2):upper(),
erakey = code:sub(3, 3):upper(),
known = l ~= nil,
text = table.concat(words, ", "),
})
end
end
if #rows == 0 and gloss == "" then return "" end
-- families in code-letter order (A Herta-Olaic, B Njeshan, C Andusian,
-- D Tacchoan, E Shung-Worrehan; X isolates last), then era, then name
table.sort(rows, function(a, b)
if a.famkey ~= b.famkey then return a.famkey < b.famkey end
if a.erakey ~= b.erakey then return a.erakey < b.erakey end
if a.name ~= b.name then return a.name < b.name end
return a.code < b.code
end)
local out = {}
table.insert(out, '<div class="translations">')
local head = "Translations"
if gloss ~= "" then
head = head .. ' — <span class="translations-gloss">' .. gloss .. '</span>'
else
head = head .. ' — <span class="translations-error">no gloss given</span>'
end
table.insert(out, '<div class="translations-head">' .. head .. '</div>')
local fam = false
for _, r in ipairs(rows) do
if r.known then
if r.family ~= fam then
if fam ~= false then table.insert(out, '</ul>') end
local cls = ' tfam-' .. r.famkey
table.insert(out, '<div class="translations-family' .. cls .. '">' .. r.family .. '</div>')
fam = r.family
table.insert(out, '<ul class="translations-list' .. cls .. '">')
end
table.insert(out, '<li>' .. r.name .. ": " .. r.text .. '</li>')
end
end
if fam ~= false then table.insert(out, '</ul>') end
for _, r in ipairs(rows) do
if not r.known then
table.insert(out, '<div class="translations-error">unrecognized code ' ..
r.code .. ': ' .. r.text .. '</div>')
end
end
table.insert(out, '</div>')
return frame:extensionTag{ name = "templatestyles", args = { src = "Template:Translations/styles.css" } }
.. table.concat(out, "\n")
end
return p