Infobox Teams row: merge IPW fields, |teams=, and research-note team codes
Story cue + same class/team rails
Line 2,265: Line 2,265:
end
end
return tostring(wrap)
return tostring(wrap)
end
local function cargoRows(tables, fields, where, limit, orderBy)
if not mw.ext or not mw.ext.cargo or not mw.ext.cargo.query then
return nil
end
local opts = {
where = where,
limit = limit or 8,
}
if orderBy and orderBy ~= '' then
opts.orderBy = orderBy
end
local ok, result = pcall(mw.ext.cargo.query, tables, fields, opts)
if not ok or type(result) ~= 'table' then
return nil
end
return result
end
local function rowField(row, ...)
for i = 1, select('#', ...) do
local key = select(i, ...)
local v = row[key]
if v ~= nil and trim(tostring(v)) ~= '' then
return trim(tostring(v))
end
end
return ''
end
local function titleToCaption(title)
title = trim(title)
local surname, given = mw.ustring.match(title, '^([^,]+),%s*(.-)%s*%(%d')
if surname and given then
return trim(given .. ' ' .. surname)
end
return title
end
local function displayFromCargoRow(row)
local page = rowField(row, 'pageName', '_pageName')
local surname = rowField(row, 'Surname')
local first = rowField(row, 'First_name', 'First name')
local middle = rowField(row, 'Middle_name', 'Middle name')
local given = trim(first .. (middle ~= '' and (' ' .. middle) or ''))
local caption
if given ~= '' and surname ~= '' then
caption = given .. ' ' .. surname
elseif page ~= '' then
caption = titleToCaption(page)
else
caption = surname
end
if page == '' and surname ~= '' then
local asn = rowField(row, 'ASN')
if asn ~= '' then
page = surname .. ', ' .. (given ~= '' and given or first) .. ' (' .. asn .. ')'
end
end
return page, caption
end
local function linkList(rows, skipAsn, skipPage, maxLinks)
local links = {}
local seen = {}
for _, row in ipairs(rows or {}) do
local asn = rowField(row, 'ASN')
local page, caption = displayFromCargoRow(row)
if caption == '' and page ~= '' then
caption = titleToCaption(page)
end
if page ~= '' and page ~= skipPage and asn ~= skipAsn and not seen[page] then
seen[page] = true
table.insert(links, string.format('[[%s|%s]]', page, caption))
if #links >= maxLinks then
break
end
end
end
return links
end
local function classFullWhere(classNum)
-- Prefer Class_number__full: the Class_number HOLDS index is corrupted on some hosts.
local n = tostring(classNum or '')
n = mw.ustring.gsub(n, '[^0-9A-Za-z%-]', '')
if n == '' then
return nil
end
return string.format(
'Class_number__full="%s" OR Class_number__full LIKE "%s;%%" OR Class_number__full LIKE "%%;%s" OR Class_number__full LIKE "%%;%s;%%"',
n,
n,
n,
n
)
end
function p.storyCue(frame)
local story = parentArg(frame, 'story')
if story == '' then
return ''
end
story = mw.ustring.gsub(story, '^%[%[', '')
story = mw.ustring.gsub(story, '%]%]$', '')
local storyTitle, storyLabel = mw.ustring.match(story, '^([^|]+)|(.+)$')
if not storyTitle then
storyTitle = story
storyLabel = nil
end
storyTitle = trim(storyTitle)
if storyLabel then
storyLabel = trim(storyLabel)
end
if not storyLabel or storyLabel == '' then
storyLabel = mw.ustring.match(storyTitle, '([^/]+)$') or storyTitle
end
local name = displayName(frame)
return string.format(
'<div class="soldier-story-cue">'
.. '<span class="soldier-story-cue-label">Full story</span> '
.. 'Read more about %s in [[%s|%s]] on \'\'[[The Stories]]\'\'.'
.. '</div>',
name,
storyTitle,
storyLabel
)
end
function p.relatedSoldiers(frame)
local asn = parentArg(frame, 'asn')
local pageTitle = mw.title.getCurrentTitle().prefixedText
local classRaw = parentArg(frame, 'class_number')
local ipwGe = parentArg(frame, 'ipw_ge')
local ipwIt = parentArg(frame, 'ipw_it')
local sections = {}
local function addTeam(label, teamPage, where)
local rows = cargoRows(
'Soldiers',
'ASN,Surname,First_name,Middle_name,_pageName=pageName',
where,
8,
'Surname'
)
local links = linkList(rows, asn, pageTitle, 8)
local head = string.format('[[%s|%s]]', teamPage, label)
local cat = 'Category:' .. teamPage
if #links > 0 then
table.insert(
sections,
'<div class="soldier-related-block"><div class="soldier-related-label">Team — '
.. head
.. '</div><div class="soldier-related-links">'
.. table.concat(links, ' · ')
.. ' · [['
.. cat
.. '|full roster]]</div></div>'
)
else
table.insert(
sections,
'<div class="soldier-related-block"><div class="soldier-related-label">Team</div>'
.. '<div class="soldier-related-links">Also assigned to '
.. head
.. ' · [['
.. cat
.. '|browse teammates]]</div></div>'
)
end
end
if ipwGe ~= '' then
local num = mw.ustring.match(ipwGe, '(%d+)') or ipwGe
addTeam('IPW ' .. num, 'Team IPW ' .. num, string.format('IPW_German="%s"', num))
end
if ipwIt ~= '' then
local num = mw.ustring.match(ipwIt, '(%d+)') or ipwIt
addTeam(
'IPW Italian ' .. num,
'Team IPW Italian ' .. num,
string.format('IPW_Italian="%s"', num)
)
end
local classes = {}
if classRaw ~= '' then
for part in mw.text.gsplit(classRaw, ';', true) do
part = trim(part)
if part ~= '' then
table.insert(classes, part)
end
end
end
for _, classNum in ipairs(classes) do
local where = classFullWhere(classNum)
local rows = where
and cargoRows(
'Soldiers',
'ASN,Surname,First_name,Middle_name,_pageName=pageName',
where,
8,
'Surname'
)
or nil
local links = linkList(rows, asn, pageTitle, 8)
local classPage = 'Class ' .. classNum
local cat = 'Category:Class ' .. classNum
if #links > 0 then
table.insert(
sections,
'<div class="soldier-related-block"><div class="soldier-related-label">Class — [['
.. classPage
.. ']]</div><div class="soldier-related-links">'
.. table.concat(links, ' · ')
.. ' · [['
.. cat
.. '|full class]]</div></div>'
)
else
table.insert(
sections,
'<div class="soldier-related-block"><div class="soldier-related-label">Class</div>'
.. '<div class="soldier-related-links">Also trained in [['
.. classPage
.. ']] · [['
.. cat
.. '|browse classmates]]</div></div>'
)
end
end
if #sections == 0 then
return ''
end
return '<div class="soldier-related">'
.. '<div class="soldier-related-heading">Same class and team</div>'
.. table.concat(sections, '\n')
.. '</div>'
end
end


return p
return p