Module:Universe: Difference between revisions
From PC Gaming Shelter
No edit summary |
No edit summary |
||
| (47 intermediate revisions by the same user not shown) | |||
| Line 1: | Line 1: | ||
local utils = require( | local utils = require("Module:Utils") | ||
local p = {} | local p = {} | ||
| Line 5: | Line 5: | ||
local function getCurrentGame() | local function getCurrentGame() | ||
local title = mw.title.getCurrentTitle() | local title = mw.title.getCurrentTitle() | ||
local game | local game = title.rootText | ||
local resource = title.subpageText | local resource = title.subpageText | ||
local data = { | local data = { | ||
[ | ["game"] = game, | ||
[ | ["resource"] = resource, | ||
} | } | ||
return data | return data | ||
| Line 15: | Line 15: | ||
local function setDisplayTitle(frame, title) | local function setDisplayTitle(frame, title) | ||
local displayTitle = frame:preprocess(string.format( | local displayTitle = frame:preprocess(string.format("{{DISPLAYTITLE:%s|noreplace, noerror}}", title)) | ||
return displayTitle | return displayTitle | ||
end | end | ||
local function escapePattern(value) | local function escapePattern(value) | ||
return value:gsub( | return value:gsub("([^%w])", "%%%1") | ||
end | end | ||
| Line 27: | Line 27: | ||
for index, link in ipairs(results) do | for index, link in ipairs(results) do | ||
results[index] = link:gsub( | results[index] = link:gsub("|" .. gamePattern .. "%s+", "|") | ||
end | end | ||
| Line 38: | Line 35: | ||
local function renameLabels(results) | local function renameLabels(results) | ||
local labels = { | local labels = { | ||
Mods = | Mods = "Mod Archive", | ||
Players = | Players = "Player Roster", | ||
Clans = | Clans = "Clan History", | ||
} | } | ||
for i, link in ipairs(results) do | for i, link in ipairs(results) do | ||
results[i] = link:gsub( | local target = link:match("^%[%[([^|%]]+)") | ||
local subpage = target and target:match("/([^/]+)$") | |||
end | local label = subpage and labels[subpage] | ||
if label then | |||
results[i] = string.format("[[%s|%s]]", target, label) | |||
else | |||
results[i] = link:gsub("|([^%]]+)%]%]", function(existingLabel) | |||
return "|" .. (labels[existingLabel] or existingLabel) .. "]]" | |||
end) | |||
end | |||
end | end | ||
| Line 61: | Line 66: | ||
table.sort(results, function(a, b) | table.sort(results, function(a, b) | ||
-- Extract the final subpage name from the link target. | -- Extract the final subpage name from the link target. | ||
local targetA = a:match( | local targetA = a:match("^%[%[:.-/([^/|%]]+)|") | ||
local targetB = b:match( | local targetB = b:match("^%[%[:.-/([^/|%]]+)|") | ||
local rankA = order[targetA] or math.huge | local rankA = order[targetA] or math.huge | ||
| Line 80: | Line 85: | ||
local function getSubpages(page) | local function getSubpages(page) | ||
local subpages = mw.smw.ask({ | local subpages = mw.smw.ask({ | ||
"[[Has parent page::" .. page .. "]][[Modification date::+]]", | |||
}) or {} | }) or {} | ||
local subpageTable = {} | local subpageTable = {} | ||
for _, subpage in ipairs(subpages) do | for _, subpage in ipairs(subpages) do | ||
local link = subpage[1] | local link = subpage[1] | ||
| Line 93: | Line 98: | ||
end | end | ||
local allGames = string.format( | local allGames = string.format("[[%s|%s]]", "Games", "All Games") | ||
table.insert(subpageTable, allGames) | table.insert(subpageTable, allGames) | ||
removeGameFromLabels(subpageTable, page) | removeGameFromLabels(subpageTable, page) | ||
renameLabels(subpageTable) | renameLabels(subpageTable) | ||
| Line 101: | Line 106: | ||
if #subpageTable == 0 then | if #subpageTable == 0 then | ||
return | return "" | ||
end | end | ||
local html = mw.html.create() | local html = mw.html.create() | ||
local universe = html:tag( | local universe = html:tag("div"):attr("id", "universeMenu"):wikitext(" | " .. table.concat(subpageTable, " | ")) | ||
return tostring(html) | return tostring(html) | ||
end | end | ||
| Line 113: | Line 118: | ||
local function formatCellValue(value) | local function formatCellValue(value) | ||
if value == nil then | if value == nil then | ||
return | return "" | ||
end | end | ||
if type(value) == | if type(value) == "table" then | ||
local values = {} | local values = {} | ||
| Line 123: | Line 128: | ||
end | end | ||
return table.concat(values, | return table.concat(values, "<br>") | ||
end | end | ||
return tostring(value) | return tostring(value) | ||
end | |||
local function formatDownloadLinks(value) | |||
if type(value) ~= "table" then | |||
return formatCellValue(value) | |||
end | |||
local links = {} | |||
for _, link in ipairs(value) do | |||
local formattedLink = formatCellValue(link) | |||
if formattedLink ~= "" then | |||
table.insert(links, formattedLink) | |||
end | |||
end | |||
return table.concat(links, "<br>") | |||
end | end | ||
local function renderModTable(content) | local function renderModTable(content) | ||
local wrapper = mw.html.create( | local wrapper = mw.html.create("div") | ||
wrapper | wrapper:attr("id", "assets") | ||
local | local tableNode = wrapper:tag("table") | ||
tableNode:addClass("smwtable-clean") | |||
for _, row in ipairs(content or {}) do | for _, row in ipairs(content or {}) do | ||
local tr = tableNode:tag( | local tr = tableNode:tag("tr") | ||
tr:tag( | tr:tag("td"):wikitext(formatCellValue(row[1])) | ||
tr:tag( | tr:tag("td"):wikitext(formatCellValue(row["Category"])) | ||
tr:tag( | tr:tag("td"):wikitext( | ||
formatCellValue(row["Has map type"]), | |||
formatCellValue(row["Has skin type"]), | |||
formatCellValue(row["Has mod type"]), | |||
formatCellValue(row["Has utility type"]) | |||
) | ) | ||
tr:tag( | tr:tag("td"):wikitext(formatCellValue(row["Has game mode"])) | ||
tr:tag( | tr:tag("td"):wikitext(formatCellValue(row["Has developer"])) | ||
tr:tag( | tr:tag("td"):wikitext(formatCellValue(row["Has release date"])) | ||
tr:tag( | tr:tag("td"):wikitext(formatCellValue(row["Has status"])) | ||
tr:tag( | tr:tag("td"):wikitext(formatCellValue(row["Has short description"])) | ||
tr:tag( | tr:tag("td"):wikitext(formatCellValue(row["Works on game version"])) | ||
tr:tag( | tr:tag("td"):wikitext(formatDownloadLinks(row["Download links"])) | ||
tr:tag( | tr:tag("td"):wikitext(formatCellValue(row["Related game"])) | ||
end | end | ||
| Line 177: | Line 183: | ||
end | end | ||
local function renderPlayerTable(content) | local function renderPlayerTable(content, panes) | ||
local wrapper = mw.html.create("div") | |||
local wrapper = mw.html.create( | wrapper:attr("id", "players"):attr("data-pane-columns", panes) | ||
wrapper | |||
local | local tableNode = wrapper:tag("table") | ||
tableNode:addClass("smwtable-clean") | |||
for _, row in ipairs(content or {}) do | for _, row in ipairs(content or {}) do | ||
| Line 202: | Line 195: | ||
local clanAndRoleValues = {} | local clanAndRoleValues = {} | ||
local member = row[ | local member = row["Member of"] | ||
if member then | if member then | ||
-- SMW may return either one value or a table of values. | -- SMW may return either one value or a table of values. | ||
local memberships = type(member) == | local memberships = type(member) == "table" and member or { member } | ||
for _, clan in ipairs(memberships) do | for _, clan in ipairs(memberships) do | ||
local formattedClan = formatCellValue(clan) | |||
table.insert(clanValues, string.format("<div>%s</div>", formattedClan)) | |||
local query = { | |||
"[[-Has subobject::" .. row[1] .. "]]", | |||
"[[Member of::" .. clan .. "]]", | |||
"?Has role#-=role", | |||
mainlabel = "-", | |||
} | |||
local results = mw.smw.ask(query) | |||
local clanRoles = {} | |||
local function addRoles(value) | |||
if value == nil or value == "" then | |||
return | |||
end | |||
for role in mw.text.gsplit(tostring(value), ",", true) do | |||
local normalizedRole = mw.text.trim(role) | |||
if normalizedRole ~= "" then | |||
table.insert(clanRoles, formatCellValue(normalizedRole)) | |||
end | |||
end | |||
end | |||
for _, resultRow in ipairs(results or {}) do | |||
local resultRoles = resultRow.role | |||
if type(resultRoles) == "table" then | |||
for _, roleValue in ipairs(resultRoles) do | |||
addRoles(roleValue) | |||
end | |||
else | |||
addRoles(resultRoles) | |||
end | |||
end | |||
if #clanRoles > 0 then | |||
local roleDivs = "<div>" .. table.concat(clanRoles, "</div><div>") .. "</div>" | |||
table.insert(roleValues, roleDivs) | |||
table.insert( | |||
clanAndRoleValues, | |||
string.format("<div>%s (%s)</div>", formattedClan, table.concat(clanRoles, ", ")) | |||
) | |||
else | |||
table.insert(roleValues, "<div>—</div>") | |||
table.insert(clanAndRoleValues, string.format("<div>%s</div>", formattedClan)) | |||
end | |||
end | end | ||
end | end | ||
local hasStatus = row["Has status"] | |||
local activeClass = "text-danger" | |||
if hasStatus == "Active" then | |||
activeClass = "text-success" | |||
end | |||
local tr = tableNode:tag("tr") | |||
tr:tag("td"):wikitext(formatCellValue(row[1])):addClass(activeClass) | |||
tr:tag("td"):wikitext(formatCellValue(row["Plays game"])) | |||
tr:tag("td"):wikitext(table.concat(clanValues, "")) | |||
tr:tag("td"):wikitext(table.concat(roleValues, "")) | |||
tr:tag("td"):wikitext(table.concat(clanAndRoleValues, "")) | |||
tr:tag("td"):wikitext(hasStatus) | |||
end | end | ||
for _, resultRow in ipairs(results or {}) do | return wrapper | ||
end | |||
local function renderClanPlayerTable(content, clanname) | |||
local title = mw.title.getCurrentTitle() | |||
local clanpage = clanname | |||
local wrapper = mw.html.create("div") | |||
wrapper:attr("id", "players"):attr("data-pane-columns", "3, 5") | |||
local tableNode = wrapper:tag("table") | |||
tableNode:addClass("smwtable-clean") | |||
for _, row in ipairs(content or {}) do | |||
local clanValues = {} | |||
local roleValues = {} | |||
local member = row["Member of"] | |||
if member then | |||
local memberships = { clanpage } | |||
for _, clan in ipairs(memberships) do | |||
local formattedClan = formatCellValue(clan) | |||
if formattedClan == clanpage then | |||
table.insert(clanValues, string.format("<div>%s</div>", formattedClan)) | |||
local query = { | |||
"[[-Has subobject::" .. row[1] .. "]]", | |||
"[[Member of::" .. clan .. "]]", | |||
"?Has role#-=role", | |||
mainlabel = "-", | |||
} | |||
local results = mw.smw.ask(query) | |||
local clanRoles = {} | |||
local function addRoles(value) | |||
if value == nil or value == "" then | |||
return | |||
end | |||
for role in mw.text.gsplit(tostring(value), ",", true) do | |||
local normalizedRole = mw.text.trim(role) | |||
if normalizedRole ~= "" then | |||
table.insert(clanRoles, formatCellValue(normalizedRole)) | |||
end | |||
end | |||
end | |||
for _, resultRow in ipairs(results or {}) do | |||
local resultRoles = resultRow.role | |||
if type(resultRoles) == "table" then | |||
for _, roleValue in ipairs(resultRoles) do | |||
addRoles(roleValue) | |||
end | |||
else | |||
addRoles(resultRoles) | |||
end | |||
end | |||
if #clanRoles > 0 then | |||
local roleDivs = table.concat(clanRoles, ", ") | |||
table.insert(roleValues, roleDivs) | |||
else | |||
table.insert(roleValues, "—") | |||
end | |||
end | |||
local hasStatus = row["Has status"] | |||
local activeClass = "text-danger" | |||
if hasStatus == "Active" then | |||
activeClass = "text-success" | |||
end | |||
local tr = tableNode:tag("tr") | |||
tr:tag("td"):wikitext(formatCellValue(row[1])):addClass(activeClass) | |||
tr:tag("td"):wikitext(formatCellValue(row["Plays game"])) | |||
tr:tag("td"):wikitext(table.concat(clanValues, "")) | |||
tr:tag("td"):wikitext(table.concat(roleValues, "")) | |||
tr:tag("td"):wikitext(table.concat(roleValues, "")) | |||
tr:tag("td"):wikitext(hasStatus) | |||
end | end | ||
end | end | ||
end | end | ||
return wrapper | |||
end | |||
local function renderClanTable(content) | |||
local wrapper = mw.html.create("div") | |||
wrapper:attr("id", "clans") | |||
local tableNode = wrapper:tag("table") | |||
tableNode:addClass("smwtable-clean") | |||
for _, row in ipairs(content or {}) do | |||
local hasStatus = formatCellValue(row["Has status"]) | |||
local statusClass = hasStatus == "Active" and "text-success" or "text-danger" | |||
local tr = tableNode:tag("tr") | |||
tr:tag("td"):wikitext(formatCellValue(row[1])):addClass(statusClass) | |||
tr:tag("td"):wikitext(formatCellValue(row["Related game"])) | |||
tr:tag("td"):wikitext(formatCellValue(row["Community links"])) | |||
tr:tag("td"):wikitext(formatCellValue(row["Has short description"])) | |||
tr:tag("td"):wikitext(hasStatus) | |||
tr:tag( | |||
tr:tag( | |||
tr:tag( | |||
tr:tag( | |||
end | end | ||
| Line 296: | Line 390: | ||
function p.Mods(frame) | function p.Mods(frame) | ||
local data | local data = getCurrentGame() | ||
local game | local game = data.game or "+" | ||
local resource = data.resource | local resource = data.resource | ||
mw.smw.set({ | mw.smw.set({ | ||
[ | ["Has parent page"] = game, | ||
}) | }) | ||
local query = { | local query = { | ||
"[[Category:Mods||Maps||Skins||Utilities]][[Related game::" .. game .. "]]", | |||
"?Related game", | |||
"?Category", | |||
"?Has mod type", | |||
"?Has map type", | |||
"?Has skin type", | |||
"?Has utility type", | |||
"?Has game mode", | |||
"?Has developer", | |||
"?Has release date#-F[Y]", | |||
"?Has status", | |||
"?Has short description", | |||
"?Works on game version", | |||
"?Download links", | |||
} | } | ||
local content = mw.smw.ask(query) | local content = mw.smw.ask(query) | ||
setDisplayTitle(frame, string.format( | --[[ | ||
local forminput = frame:callParserFunction({ | |||
name = "#forminput", | |||
"", | |||
args = { | |||
"form=Mod", | |||
"query string=Mod[Related game]=" .. game, | |||
"button text=Create or Edit Mod", | |||
"autofocus=no", | |||
}, | |||
}) | |||
]]-- | |||
setDisplayTitle(frame, string.format("%s %s", game, resource)) | |||
local html = mw.html.create() | local html = mw.html.create() | ||
html:wikitext(getSubpages(game)) | html:wikitext(getSubpages(game)) | ||
html:wikitext(forminput) | -- html:wikitext(forminput) | ||
html:node(renderModTable(content)) | html:node(renderModTable(content)) | ||
return html | return html | ||
end | end | ||
function p.allMods(frame) | function p.allMods(frame) | ||
local query = { | local query = { | ||
"[[Category:Mods||Maps||Skins||Utilities]][[Related game::+]]", | |||
"?Related game", | |||
"?Category", | |||
"?Has mod type", | |||
"?Has map type", | |||
"?Has skin type", | |||
"?Has utility type", | |||
"?Has game mode", | |||
"?Has developer", | |||
"?Has release date#-F[Y]", | |||
"?Has status", | |||
"?Has short description", | |||
"?Works on game version", | |||
"?Download links", | |||
} | } | ||
local content = mw.smw.ask(query) | local content = mw.smw.ask(query) | ||
| Line 361: | Line 460: | ||
local html = mw.html.create() | local html = mw.html.create() | ||
html:node(renderModTable(content, true)) | html:node(renderModTable(content, true)) | ||
return html | return html | ||
end | end | ||
function p.Players(frame) | function p.Players(frame) | ||
local data | local data = getCurrentGame() | ||
local game | local game = data.game | ||
local resource = data.resource | local resource = data.resource | ||
mw.smw.set({ | mw.smw.set({ | ||
[ | ["Has parent page"] = game, | ||
}) | }) | ||
local query = { | local query = { | ||
"[[Category:Players]][[Plays game::" .. game .. "]]", | |||
"?Plays game", | |||
"?Member of", | |||
"?Has status", | |||
} | } | ||
local content = mw.smw.ask(query) | local content = mw.smw.ask(query) | ||
setDisplayTitle(frame, string.format( | --[[ | ||
local forminput = frame:callParserFunction({ | |||
name = "#forminput", | |||
"", | |||
args = { | |||
"form=Player", | |||
"query string=Player[Plays game]=" .. game, | |||
"button text=Create or Edit Player Entry", | |||
"autocomplete on category=Players", | |||
"autofocus=no", | |||
}, | |||
}) | |||
]]-- | |||
setDisplayTitle(frame, string.format("%s %s", game, resource)) | |||
local html = mw.html.create() | local html = mw.html.create() | ||
html:wikitext(getSubpages(game)) | html:wikitext(getSubpages(game)) | ||
html:wikitext(forminput) | -- html:wikitext(forminput) | ||
html:node(renderPlayerTable(content)) | html:node(renderPlayerTable(content, "2, 3, 5")) | ||
return html | return html | ||
end | end | ||
function p.allPlayers(frame) | function p.allPlayers(frame) | ||
local query = { | |||
"[[Category:Players]][[Plays game::+]]", | |||
"?Plays game", | |||
"?Member of", | |||
"?Has status", | |||
} | |||
local content = mw.smw.ask(query) | |||
local html = mw.html.create() | |||
html:node(renderPlayerTable(content, "1, 2, 3, 5")) | |||
return html | |||
end | |||
function p.clanPlayers(frame) | |||
local title = mw.title.getCurrentTitle() | |||
local clan = title.fullText | |||
local query = { | local query = { | ||
"[[Member of::" .. clan .. "]][[Modification date::+]]", | |||
"?Plays game", | |||
"?Member of", | |||
"?Has status", | |||
} | } | ||
local content = mw.smw.ask(query) | local content = mw.smw.ask(query) | ||
local html = mw.html.create() | local html = mw.html.create() | ||
html:node( | html:node(renderClanPlayerTable(content, clan)) | ||
return html | return html | ||
end | end | ||
function p.Clans(frame) | function p.Clans(frame) | ||
local data | local data = getCurrentGame() | ||
local game | local game = data.game | ||
local resource = data.resource | local resource = data.resource | ||
mw.smw.set({ | mw.smw.set({ | ||
[ | ["Has parent page"] = game, | ||
}) | }) | ||
local query = { | local query = { | ||
"[[Category:Communities]][[Related game::" .. game .. "]]", | |||
"?Related game", | |||
"?Community links", | |||
"?Has short description", | |||
"?Has status", | |||
} | } | ||
local content = mw.smw.ask(query) | local content = mw.smw.ask(query) | ||
--[[ | |||
local forminput = frame:callParserFunction({ | |||
name = "#forminput", | |||
"", | |||
args = { | |||
"form=Community", | |||
"query string=Community[Related game]=" .. game, | |||
"button text=Create or Edit Community Entry", | |||
"autocomplete on category=Communities", | |||
"autofocus=no", | |||
}, | |||
}) | |||
]]-- | |||
local html = mw.html.create() | local html = mw.html.create() | ||
html:wikitext(getSubpages(game)) | html:wikitext(getSubpages(game)) | ||
html:wikitext(forminput) | -- html:wikitext(forminput) | ||
html:node(renderClanTable(content)) | |||
return html | |||
end | |||
function p.allClans(frame) | |||
local args = frame.args | |||
local hasStatus = args.hasStatus or "+" | |||
local query = { | |||
"[[Category:Communities]][[Has status::" .. hasStatus .. "]]", | |||
"?Related game", | |||
"?Community links", | |||
"?Has short description", | |||
"?Has status", | |||
} | |||
local content = mw.smw.ask(query) | |||
--[[ | |||
local forminput = frame:callParserFunction({ | |||
name = "#forminput", | |||
"", | |||
args = { | |||
"form=Community", | |||
"query string=Community[Has status]=" .. hasStatus, | |||
"button text=Create or Edit Community Entry", | |||
"autocomplete on category=Communities", | |||
"autofocus=no", | |||
}, | |||
}) | |||
]]-- | |||
local html = mw.html.create() | |||
-- html:wikitext(forminput) | |||
html:node(renderClanTable(content)) | |||
return html | return html | ||
end | end | ||
return p | return p | ||
Latest revision as of 09:05, 11 August 2026
Documentation for this module may be created at Module:Universe/doc
local utils = require("Module:Utils")
local p = {}
local function getCurrentGame()
local title = mw.title.getCurrentTitle()
local game = title.rootText
local resource = title.subpageText
local data = {
["game"] = game,
["resource"] = resource,
}
return data
end
local function setDisplayTitle(frame, title)
local displayTitle = frame:preprocess(string.format("{{DISPLAYTITLE:%s|noreplace, noerror}}", title))
return displayTitle
end
local function escapePattern(value)
return value:gsub("([^%w])", "%%%1")
end
local function removeGameFromLabels(results, game)
local gamePattern = escapePattern(game)
for index, link in ipairs(results) do
results[index] = link:gsub("|" .. gamePattern .. "%s+", "|")
end
return results
end
local function renameLabels(results)
local labels = {
Mods = "Mod Archive",
Players = "Player Roster",
Clans = "Clan History",
}
for i, link in ipairs(results) do
local target = link:match("^%[%[([^|%]]+)")
local subpage = target and target:match("/([^/]+)$")
local label = subpage and labels[subpage]
if label then
results[i] = string.format("[[%s|%s]]", target, label)
else
results[i] = link:gsub("|([^%]]+)%]%]", function(existingLabel)
return "|" .. (labels[existingLabel] or existingLabel) .. "]]"
end)
end
end
return results
end
local function sortSubpages(results)
local order = {
Mods = 1,
Players = 2,
Clans = 3,
}
table.sort(results, function(a, b)
-- Extract the final subpage name from the link target.
local targetA = a:match("^%[%[:.-/([^/|%]]+)|")
local targetB = b:match("^%[%[:.-/([^/|%]]+)|")
local rankA = order[targetA] or math.huge
local rankB = order[targetB] or math.huge
if rankA ~= rankB then
return rankA < rankB
end
-- Keep all remaining subpages alphabetically ordered.
return (targetA or a) < (targetB or b)
end)
return results
end
local function getSubpages(page)
local subpages = mw.smw.ask({
"[[Has parent page::" .. page .. "]][[Modification date::+]]",
}) or {}
local subpageTable = {}
for _, subpage in ipairs(subpages) do
local link = subpage[1]
if link then
table.insert(subpageTable, link)
end
end
local allGames = string.format("[[%s|%s]]", "Games", "All Games")
table.insert(subpageTable, allGames)
removeGameFromLabels(subpageTable, page)
renameLabels(subpageTable)
sortSubpages(subpageTable)
if #subpageTable == 0 then
return ""
end
local html = mw.html.create()
local universe = html:tag("div"):attr("id", "universeMenu"):wikitext(" | " .. table.concat(subpageTable, " | "))
return tostring(html)
end
local function formatCellValue(value)
if value == nil then
return ""
end
if type(value) == "table" then
local values = {}
for _, item in ipairs(value) do
table.insert(values, tostring(item))
end
return table.concat(values, "<br>")
end
return tostring(value)
end
local function formatDownloadLinks(value)
if type(value) ~= "table" then
return formatCellValue(value)
end
local links = {}
for _, link in ipairs(value) do
local formattedLink = formatCellValue(link)
if formattedLink ~= "" then
table.insert(links, formattedLink)
end
end
return table.concat(links, "<br>")
end
local function renderModTable(content)
local wrapper = mw.html.create("div")
wrapper:attr("id", "assets")
local tableNode = wrapper:tag("table")
tableNode:addClass("smwtable-clean")
for _, row in ipairs(content or {}) do
local tr = tableNode:tag("tr")
tr:tag("td"):wikitext(formatCellValue(row[1]))
tr:tag("td"):wikitext(formatCellValue(row["Category"]))
tr:tag("td"):wikitext(
formatCellValue(row["Has map type"]),
formatCellValue(row["Has skin type"]),
formatCellValue(row["Has mod type"]),
formatCellValue(row["Has utility type"])
)
tr:tag("td"):wikitext(formatCellValue(row["Has game mode"]))
tr:tag("td"):wikitext(formatCellValue(row["Has developer"]))
tr:tag("td"):wikitext(formatCellValue(row["Has release date"]))
tr:tag("td"):wikitext(formatCellValue(row["Has status"]))
tr:tag("td"):wikitext(formatCellValue(row["Has short description"]))
tr:tag("td"):wikitext(formatCellValue(row["Works on game version"]))
tr:tag("td"):wikitext(formatDownloadLinks(row["Download links"]))
tr:tag("td"):wikitext(formatCellValue(row["Related game"]))
end
return wrapper
end
local function renderPlayerTable(content, panes)
local wrapper = mw.html.create("div")
wrapper:attr("id", "players"):attr("data-pane-columns", panes)
local tableNode = wrapper:tag("table")
tableNode:addClass("smwtable-clean")
for _, row in ipairs(content or {}) do
local clanValues = {}
local roleValues = {}
local clanAndRoleValues = {}
local member = row["Member of"]
if member then
-- SMW may return either one value or a table of values.
local memberships = type(member) == "table" and member or { member }
for _, clan in ipairs(memberships) do
local formattedClan = formatCellValue(clan)
table.insert(clanValues, string.format("<div>%s</div>", formattedClan))
local query = {
"[[-Has subobject::" .. row[1] .. "]]",
"[[Member of::" .. clan .. "]]",
"?Has role#-=role",
mainlabel = "-",
}
local results = mw.smw.ask(query)
local clanRoles = {}
local function addRoles(value)
if value == nil or value == "" then
return
end
for role in mw.text.gsplit(tostring(value), ",", true) do
local normalizedRole = mw.text.trim(role)
if normalizedRole ~= "" then
table.insert(clanRoles, formatCellValue(normalizedRole))
end
end
end
for _, resultRow in ipairs(results or {}) do
local resultRoles = resultRow.role
if type(resultRoles) == "table" then
for _, roleValue in ipairs(resultRoles) do
addRoles(roleValue)
end
else
addRoles(resultRoles)
end
end
if #clanRoles > 0 then
local roleDivs = "<div>" .. table.concat(clanRoles, "</div><div>") .. "</div>"
table.insert(roleValues, roleDivs)
table.insert(
clanAndRoleValues,
string.format("<div>%s (%s)</div>", formattedClan, table.concat(clanRoles, ", "))
)
else
table.insert(roleValues, "<div>—</div>")
table.insert(clanAndRoleValues, string.format("<div>%s</div>", formattedClan))
end
end
end
local hasStatus = row["Has status"]
local activeClass = "text-danger"
if hasStatus == "Active" then
activeClass = "text-success"
end
local tr = tableNode:tag("tr")
tr:tag("td"):wikitext(formatCellValue(row[1])):addClass(activeClass)
tr:tag("td"):wikitext(formatCellValue(row["Plays game"]))
tr:tag("td"):wikitext(table.concat(clanValues, ""))
tr:tag("td"):wikitext(table.concat(roleValues, ""))
tr:tag("td"):wikitext(table.concat(clanAndRoleValues, ""))
tr:tag("td"):wikitext(hasStatus)
end
return wrapper
end
local function renderClanPlayerTable(content, clanname)
local title = mw.title.getCurrentTitle()
local clanpage = clanname
local wrapper = mw.html.create("div")
wrapper:attr("id", "players"):attr("data-pane-columns", "3, 5")
local tableNode = wrapper:tag("table")
tableNode:addClass("smwtable-clean")
for _, row in ipairs(content or {}) do
local clanValues = {}
local roleValues = {}
local member = row["Member of"]
if member then
local memberships = { clanpage }
for _, clan in ipairs(memberships) do
local formattedClan = formatCellValue(clan)
if formattedClan == clanpage then
table.insert(clanValues, string.format("<div>%s</div>", formattedClan))
local query = {
"[[-Has subobject::" .. row[1] .. "]]",
"[[Member of::" .. clan .. "]]",
"?Has role#-=role",
mainlabel = "-",
}
local results = mw.smw.ask(query)
local clanRoles = {}
local function addRoles(value)
if value == nil or value == "" then
return
end
for role in mw.text.gsplit(tostring(value), ",", true) do
local normalizedRole = mw.text.trim(role)
if normalizedRole ~= "" then
table.insert(clanRoles, formatCellValue(normalizedRole))
end
end
end
for _, resultRow in ipairs(results or {}) do
local resultRoles = resultRow.role
if type(resultRoles) == "table" then
for _, roleValue in ipairs(resultRoles) do
addRoles(roleValue)
end
else
addRoles(resultRoles)
end
end
if #clanRoles > 0 then
local roleDivs = table.concat(clanRoles, ", ")
table.insert(roleValues, roleDivs)
else
table.insert(roleValues, "—")
end
end
local hasStatus = row["Has status"]
local activeClass = "text-danger"
if hasStatus == "Active" then
activeClass = "text-success"
end
local tr = tableNode:tag("tr")
tr:tag("td"):wikitext(formatCellValue(row[1])):addClass(activeClass)
tr:tag("td"):wikitext(formatCellValue(row["Plays game"]))
tr:tag("td"):wikitext(table.concat(clanValues, ""))
tr:tag("td"):wikitext(table.concat(roleValues, ""))
tr:tag("td"):wikitext(table.concat(roleValues, ""))
tr:tag("td"):wikitext(hasStatus)
end
end
end
return wrapper
end
local function renderClanTable(content)
local wrapper = mw.html.create("div")
wrapper:attr("id", "clans")
local tableNode = wrapper:tag("table")
tableNode:addClass("smwtable-clean")
for _, row in ipairs(content or {}) do
local hasStatus = formatCellValue(row["Has status"])
local statusClass = hasStatus == "Active" and "text-success" or "text-danger"
local tr = tableNode:tag("tr")
tr:tag("td"):wikitext(formatCellValue(row[1])):addClass(statusClass)
tr:tag("td"):wikitext(formatCellValue(row["Related game"]))
tr:tag("td"):wikitext(formatCellValue(row["Community links"]))
tr:tag("td"):wikitext(formatCellValue(row["Has short description"]))
tr:tag("td"):wikitext(hasStatus)
end
return wrapper
end
function p.Mods(frame)
local data = getCurrentGame()
local game = data.game or "+"
local resource = data.resource
mw.smw.set({
["Has parent page"] = game,
})
local query = {
"[[Category:Mods||Maps||Skins||Utilities]][[Related game::" .. game .. "]]",
"?Related game",
"?Category",
"?Has mod type",
"?Has map type",
"?Has skin type",
"?Has utility type",
"?Has game mode",
"?Has developer",
"?Has release date#-F[Y]",
"?Has status",
"?Has short description",
"?Works on game version",
"?Download links",
}
local content = mw.smw.ask(query)
--[[
local forminput = frame:callParserFunction({
name = "#forminput",
"",
args = {
"form=Mod",
"query string=Mod[Related game]=" .. game,
"button text=Create or Edit Mod",
"autofocus=no",
},
})
]]--
setDisplayTitle(frame, string.format("%s %s", game, resource))
local html = mw.html.create()
html:wikitext(getSubpages(game))
-- html:wikitext(forminput)
html:node(renderModTable(content))
return html
end
function p.allMods(frame)
local query = {
"[[Category:Mods||Maps||Skins||Utilities]][[Related game::+]]",
"?Related game",
"?Category",
"?Has mod type",
"?Has map type",
"?Has skin type",
"?Has utility type",
"?Has game mode",
"?Has developer",
"?Has release date#-F[Y]",
"?Has status",
"?Has short description",
"?Works on game version",
"?Download links",
}
local content = mw.smw.ask(query)
local html = mw.html.create()
html:node(renderModTable(content, true))
return html
end
function p.Players(frame)
local data = getCurrentGame()
local game = data.game
local resource = data.resource
mw.smw.set({
["Has parent page"] = game,
})
local query = {
"[[Category:Players]][[Plays game::" .. game .. "]]",
"?Plays game",
"?Member of",
"?Has status",
}
local content = mw.smw.ask(query)
--[[
local forminput = frame:callParserFunction({
name = "#forminput",
"",
args = {
"form=Player",
"query string=Player[Plays game]=" .. game,
"button text=Create or Edit Player Entry",
"autocomplete on category=Players",
"autofocus=no",
},
})
]]--
setDisplayTitle(frame, string.format("%s %s", game, resource))
local html = mw.html.create()
html:wikitext(getSubpages(game))
-- html:wikitext(forminput)
html:node(renderPlayerTable(content, "2, 3, 5"))
return html
end
function p.allPlayers(frame)
local query = {
"[[Category:Players]][[Plays game::+]]",
"?Plays game",
"?Member of",
"?Has status",
}
local content = mw.smw.ask(query)
local html = mw.html.create()
html:node(renderPlayerTable(content, "1, 2, 3, 5"))
return html
end
function p.clanPlayers(frame)
local title = mw.title.getCurrentTitle()
local clan = title.fullText
local query = {
"[[Member of::" .. clan .. "]][[Modification date::+]]",
"?Plays game",
"?Member of",
"?Has status",
}
local content = mw.smw.ask(query)
local html = mw.html.create()
html:node(renderClanPlayerTable(content, clan))
return html
end
function p.Clans(frame)
local data = getCurrentGame()
local game = data.game
local resource = data.resource
mw.smw.set({
["Has parent page"] = game,
})
local query = {
"[[Category:Communities]][[Related game::" .. game .. "]]",
"?Related game",
"?Community links",
"?Has short description",
"?Has status",
}
local content = mw.smw.ask(query)
--[[
local forminput = frame:callParserFunction({
name = "#forminput",
"",
args = {
"form=Community",
"query string=Community[Related game]=" .. game,
"button text=Create or Edit Community Entry",
"autocomplete on category=Communities",
"autofocus=no",
},
})
]]--
local html = mw.html.create()
html:wikitext(getSubpages(game))
-- html:wikitext(forminput)
html:node(renderClanTable(content))
return html
end
function p.allClans(frame)
local args = frame.args
local hasStatus = args.hasStatus or "+"
local query = {
"[[Category:Communities]][[Has status::" .. hasStatus .. "]]",
"?Related game",
"?Community links",
"?Has short description",
"?Has status",
}
local content = mw.smw.ask(query)
--[[
local forminput = frame:callParserFunction({
name = "#forminput",
"",
args = {
"form=Community",
"query string=Community[Has status]=" .. hasStatus,
"button text=Create or Edit Community Entry",
"autocomplete on category=Communities",
"autofocus=no",
},
})
]]--
local html = mw.html.create()
-- html:wikitext(forminput)
html:node(renderClanTable(content))
return html
end
return p
