Module:ResourceList
From PC Gaming Shelter
Documentation for this module may be created at Module:ResourceList/doc
local p = {}
local FIELDS = {
{
key = "resources",
title = "Type",
property = "Has resource type",
},
{
key = "types",
title = "Content",
property = "Has content type",
},
{
key = "langs",
title = "Language",
property = "Has language",
},
{
key = "years",
title = "Year",
property = "Has date",
},
}
local function trim(value)
return mw.text.trim(tostring(value or ""))
end
local function valueText(value)
if type(value) ~= "table" then
return trim(value)
end
return trim(
value.fulltext
or value.fullText
or value.label
or value.text
or value.displaytitle
or value[1]
or ""
)
end
local function addValue(bucket, rawValue)
local value = valueText(rawValue)
if value == "" then
return
end
local key = mw.ustring.lower(value)
if bucket.counts[key] == nil then
bucket.counts[key] = 0
bucket.labels[key] = value
end
bucket.counts[key] = bucket.counts[key] + 1
end
local function collect(rows)
local buckets = {}
for _, field in ipairs(FIELDS) do
buckets[field.key] = {
counts = {},
labels = {},
}
end
for _, row in ipairs(rows) do
for _, field in ipairs(FIELDS) do
local values = row[field.key]
local bucket = buckets[field.key]
if type(values) == "table" then
for _, value in ipairs(values) do
addValue(bucket, value)
end
else
addValue(bucket, values)
end
end
end
return buckets
end
local function sortedKeys(bucket)
local keys = {}
for key in pairs(bucket.counts) do
table.insert(keys, key)
end
table.sort(keys, function(a, b)
return mw.ustring.lower(bucket.labels[a]) < mw.ustring.lower(bucket.labels[b])
end)
return keys
end
local function queryFormLink(frame, game, propertyName, item)
return frame:preprocess(string.format(
"{{#queryformlink: form=Resource filter" ..
"|link text=%s" ..
"|Resource filter[Related game]=%s" ..
"|Resource filter[%s]=%s" ..
"|Resource filter[Has filter]=%s" ..
"|_run=1" ..
"}}",
item,
game,
propertyName,
item,
propertyName
))
end
local function renderList(frame, field, bucket, game, showCounts)
local html = mw.html.create()
local resItem = html:tag('div'):addClass('card bg-transparent flex-md-row mb-2')
resItem:tag('div'):addClass('resources-header'):wikitext(field.title)
local cardBody = resItem:tag('div'):addClass('d-flex flex-wrap px-3 text-muted'):css({
['gap'] = '0 .5rem'
})
local keys = sortedKeys(bucket)
if #keys == 0 then
cardBody:tag('div'):wikitext("None found.")
return html
end
for _, key in ipairs(keys) do
local label = bucket.labels[key]
local link = queryFormLink(frame, game, field.property, label)
if showCounts then
cardBody:tag('div'):wikitext(link .. " (" .. bucket.counts[key] .. ")")
else
cardBody:tag('div'):wikitext(link)
end
end
return html
end
local function askRows(args)
local game = args.game
if not game then
return
end
local limit = args.limit or "5000"
return mw.smw.ask({
"[[Resource:+]]",
"[[Related game::" .. game .. "]]",
"?Has resource type=resources",
"?Has content type=types",
"?Has language=langs",
"?Has date#-F[Y]=years",
"limit=" .. limit,
"mainlabel=-",
}) or {}
end
function p.render(frame)
local parent = frame:getParent()
local args = setmetatable(frame.args, {
__index = parent and parent.args or {},
})
local game = args.game or "Half-Life"
local showCounts = args.counts ~= "no"
local rows = askRows(args)
local buckets = collect(rows)
local html = mw.html.create()
local res = html:tag('div'):attr('id', 'more-resources')
res:tag('h2'):wikitext('External Resources')
for _, field in ipairs(FIELDS) do
res:node(renderList(frame, field, buckets[field.key], game, showCounts))
end
return html
end
function p.filtered(frame)
local item = frame.args['item']
local parent = frame:getParent()
local args = setmetatable(frame.args, {
__index = parent and parent.args or {},
})
local game = args['Related game']
local filter = args['Has filter']
local query = frame:callParserFunction("#ask", {
"[[Resource:+]][[Related game::" .. game .. "]][[" .. filter .. "::~" .. item .. "]]",
"format=embedded",
"embedformat=h5",
"limit=5000",
})
return query
end
p.main = p.render
return p
