Module:Featured articles

Jump to navigation Jump to search
[view] [edit] [history] [refresh]The above documentation is transcluded from Module:Featured articles/doc.
--- Various utils for featured articles
local p = {}

local function getLastItem(str)
  local parts = {}
  for s in string.gmatch(str, "([^/]+)") do
    table.insert(parts, s)
  end
  return parts[#parts]
end

local function nextWeek(increment, cadence)
	local currentWeek = tonumber(mw.getCurrentFrame():preprocess("{{CURRENTWEEK}}"))
	local year = tonumber(mw.getCurrentFrame():preprocess("{{CURRENTYEAR}}"))
	local lastWeekOfYear = tonumber(mw.getCurrentFrame():preprocess("{{#time:W|" .. year .. "-12-28}}"))
	local targetWeek = currentWeek + increment
	if year > 2025 or targetWeek >= 14 then -- two-week cadence implemented since week 14 of 2025
		targetWeek = targetWeek - (targetWeek % cadence)
	end
	local targetYear = year

	if targetWeek > lastWeekOfYear then
		targetYear = year + 1
		targetWeek = targetWeek - lastWeekOfYear
	elseif targetWeek <= 0 then
		targetYear = year - 1
		local prevYearWeeks = tonumber(mw.getCurrentFrame():preprocess("{{#time:W|" .. targetYear .. "-12-28}}"))
		targetWeek = prevYearWeeks + targetWeek
	end

	return {targetWeek, targetYear}
end

function p.nextWeek(frame)
	return nextWeek(tonumber(frame.args[1] or 1), tonumber(frame.args[2] or 1))[1]
end

function p.escapeArgs(frame)
	return frame:callParserFunction( '#tag', { 'nowiki', frame:getParent().args[frame.args[1]] } )
end

local function entryCell(articleType, index, frame)
	local cadence = articleType == 'Minecraft' and 1 or 2
	local nextWeekResult = nextWeek(index, cadence)
	local year = nextWeekResult[2]
	local week = nextWeekResult[1]
	local query = mw.smw.ask({
		"[[Featured article title::+]]",
		"[[Featured article type::" .. articleType .."]]",
		"[[Featured article year::" .. year .."]]",
		"[[Featured article week::" .. week .."]]",
		"? = #",
		"?Featured article title #"
	})
	if query then
		local cell = query[1]
		local title = cell['Featured article title']
		if articleType ~= 'Minecraft' then
			title = string.gsub(title, articleType .. ':', '')
		end
		return {
			exists = true,
			week = week,
			link = '[[' .. cell[1] .. '|' .. title .. ']]'
		}
	else
		local editUrl = frame:callParserFunction('fullurl', {
			'MCW:Featured articles/' .. articleType .. '/' .. year .. '/' .. week,
			'action=edit&preload=MCW:Featured_articles/entry_preload',
		})
		return {
			exists = false,
			week = week,
			link = '[' .. editUrl .. ' Missing]'
		}
	end
end

function p.entryCell(frame)
	local cell = entryCell(frame.args[1] or 'Minecraft', tonumber(frame.args[2] or 0), frame)
	if not cell.exists then
		return frame:expandTemplate{ title = 'tc', args = { 'no', cell.link } }
	else
		return cell.link
	end
end

function p.queueTable(frame)
	local result = '{| class="wikitable"\n' ..
				   '|+ Featured article queue\n' ..
				   '|-\n' ..
				   '! Week\n'

	local headers = { 'Minecraft', 'Movie', 'Dungeons', 'Legends', 'Story Mode', 'Earth' }
	for _, header in ipairs(headers) do
		result = result .. '! [[MCW:Featured articles/' .. header .. '|' .. header .. ']]\n'
	end

	local minRow, maxRow = -1, 4
	local columns = {}

	for _, col in ipairs(headers) do
		local week = -1
		for row = minRow, maxRow do
			local cell = entryCell(col, row, frame)

			if columns[col] == nil then columns[col] = {} end
			local column = columns[col]

			if week == cell.week then
				columns[col][#column].rowspan = column[#column].rowspan + 1
			else
				week = cell.week
				cell.rowspan = 1
				table.insert(columns[col], cell)
			end

			if not cell.exists then
				columns[col][#column].color = 'no'
			elseif row == 0 then
				columns[col][#column].color = 'yes'
			end
		end
	end
	
	for row = minRow, maxRow do
		local week = nextWeek(row, 1)[1]
		local weekText = week
		if row == 0 then
			weekText = frame:expandTemplate{ title = 'tc', args = { 'always', week } }
		end

		result = result ..
			'|-\n' ..
			'! ' .. weekText .. '\n'
		
		for _, col in ipairs(headers) do
			if columns[col] == nil then columns[col] = {} end
			local cell = columns[col][1]

			if cell then
				if not cell.rendered then
					result = result .. '| '
					if cell.color then
						result = result .. frame:expandTemplate{ title = 'tc', args = { cell.color, cell.link, rowspan = cell.rowspan } }
					else
						result = result .. 'rowspan=' .. cell.rowspan .. ' | ' .. cell.link
					end
					columns[col][1].rendered = true
	
					result = result .. '\n'
				end
	
				columns[col][1].rowspan = cell.rowspan - 1
				if columns[col][1].rowspan == 0 then
					table.remove(columns[col], 1)
				end
			end
		end
	end

	result = result .. '|}'

	return result
end

function p.archiveTable(frame)
	local result = '{| class="wikitable"\n' ..
				   '|-\n' ..
				   '! Week !! Article\n'
	
	local smwdata = mw.smw.ask({
		"[[Featured article title::+]]",
		"[[Featured article type::" .. frame.args[1] .."]]",
		"[[Featured article year::" .. frame.args[2] .."]]",
		"? = #",
		"?Featured article title #"
	})

	if smwdata then
		for i, v in ipairs(smwdata) do
			result = result ..
					 '|-\n' ..
					 '| [[' .. v[1] .. '|' .. getLastItem(v[1]) .. ']]\n' ..
					 '| [[' .. v['Featured article title'] .. ']]\n'
		end
	end

	result = result .. '|}'

	return result
end

return p