Jump to content

Module:Random portal component/sandbox: Difference between revisions

From Wikipedia, the free encyclopedia
Content deleted Content added
fix isRootPortalTitle arg
only check the boundary pages to find out which subpage tracking category a portal should be placed in; this reduces the maximum number of expensive function calls to 13, and removes the need for the "max" argument
Line 36: Line 36:
end
end


local function subPageTrackingCategories(pages, max, header)
local function makeCategoryLink(category)
-- Make a category link.
local retval = "";
return string.format('[[Category:%s]]', category)
local availableSubPageCount = 0;
end
local i;

local function makeSubpageTrackingCategoryLink(fragment)
-- Make a subpage tracking category link.
return makeCategoryLink(
string.format(
'Random portal component with %s available subpages',
fragment
)
)
end

local function renderSubpageTrackingCategory(pages, header)
-- Render the link for the appropriate subpage tracking category.


-- Only track root portal pages that have "Selected x" sections.
-- Only track root portal pages that have "Selected x" sections.
Line 46: Line 59:
end
end


-- Check whether subpages exist at the category boundaries, and return the
-- limit checking to prevent Lua overload
-- appropriate category link. For example, if page 6 exists but page 11
local myMaxCheck = 60
-- doesn't, return
if tonumber(max) < myMaxCheck then
-- [[Category:Random portal component with 6–10 available subpages]].
myMaxCheck = tonumber(max)
local boundaries = {2, 6, 11, 16, 21, 26, 31, 41, 51, 101, 201, 501, 1001}
end
local fragment
for i=1,myMaxCheck do
for i, subpageNumber in ipairs(boundaries) do
local aSubPage = mw.title.new(pages.subpage .. '/' .. i)
local subpageName = pages.subpage .. '/' .. tostring(subpageNumber)
if (aSubPage.exists) then
local subpageTitle = mw.title.new(subpageName)
availableSubPageCount = availableSubPageCount + 1;
if not subpageTitle.exists then
if i == 1 then
fragment = string.format("less than %d", boundaries[i])
else
fragment = string.format("%d–%d", boundaries[i - 1], boundaries[i] - 1)
end
return makeSubpageTrackingCategoryLink(fragment)
end
end
end
end
fragment = string.format("over %d", boundaries[#boundaries] - 1)
if myMaxCheck >= tonumber(max) then
return makeSubpageTrackingCategoryLink(fragment)
if (availableSubPageCount < tonumber(max)) then
retval = retval .. "[[Category:Random portal component with fewer available subpages than specified max]]"
elseif (availableSubPageCount > tonumber(max)) then
retval = retval .. "[[Category:Random portal component with more available subpages than specified max]]"
end
end
if (availableSubPageCount < 2) then
retval = retval .. "[[Category:Random portal component with less than 2 available subpages]]"
elseif (availableSubPageCount <= 5) then
retval = retval .. "[[Category:Random portal component with 2–5 available subpages]]"
elseif (availableSubPageCount <= 10) then
retval = retval .. "[[Category:Random portal component with 6–10 available subpages]]"
elseif (availableSubPageCount <= 15) then
retval = retval .. "[[Category:Random portal component with 11–15 available subpages]]"
elseif (availableSubPageCount <= 20) then
retval = retval .. "[[Category:Random portal component with 16–20 available subpages]]"
elseif (availableSubPageCount <= 25) then
retval = retval .. "[[Category:Random portal component with 21–25 available subpages]]"
elseif (availableSubPageCount <= 30) then
retval = retval .. "[[Category:Random portal component with 26–30 available subpages]]"
elseif (availableSubPageCount <= 40) then
retval = retval .. "[[Category:Random portal component with 31–40 available subpages]]"
elseif (availableSubPageCount <= 50) then
retval = retval .. "[[Category:Random portal component with 41–50 available subpages]]"
else
retval = retval .. "[[Category:Random portal component with over 50 available subpages]]"
end
return retval;
end
end


Line 170: Line 163:
end
end


return table.concat(ret, '\n') .. subPageTrackingCategories(pages, args.max, args.header)
return table.concat(ret, '\n') .. renderSubpageTrackingCategory(pages, args.header)
end
end


Line 187: Line 180:
))
))


return table.concat(ret, '\n') .. subPageTrackingCategories(pages, args.max, args.header)
return table.concat(ret, '\n') .. renderSubpageTrackingCategory(pages, args.header)
end
end



Revision as of 09:27, 2 May 2019

-- This module implements [[Template:Random portal component]]

local p = {}

local mRandom = require('Module:Random')
local currentTitle = mw.title.getCurrentTitle()

local portalNamesContainingSlashes = {
	["AC/DC"] = true,
}

local function isSelectedHeader(header)
	-- Whether a page is selected (a selected article, selected list, etc.).
	-- The "'*" part of the pattern checks for italic or bold text, like
	-- ''Selected'' or '''Selected'''.
	return string.find(header, "^'*[sS]elected") ~= nil
end

local function isInPortalNamespace(title)
	-- Whether a title object is in the portal namespace.
	return title.namespace == 100
end

local function isPortalSubpage(title)
	-- Whether a title object is a portal subpage
	return (
		isInPortalNamespace(title)
		and title.isSubpage
		and not portalNamesContainingSlashes[title.text]
	)
end

local function isRootPortalTitle(title)
	-- Whether a title object is for a root portal page.
	return isInPortalNamespace(title) and not isPortalSubpage(title)
end

local function makeCategoryLink(category)
	-- Make a category link.
	return string.format('[[Category:%s]]', category)
end

local function makeSubpageTrackingCategoryLink(fragment)
	-- Make a subpage tracking category link.
	return makeCategoryLink(
		string.format(
			'Random portal component with %s available subpages',
			fragment
		)
	)
end

local function renderSubpageTrackingCategory(pages, header)
	-- Render the link for the appropriate subpage tracking category.

	-- Only track root portal pages that have "Selected x" sections.
	if not isSelectedHeader(header) or not isRootPortalTitle(currentTitle) then
		return ""
	end

	-- Check whether subpages exist at the category boundaries, and return the
	-- appropriate category link. For example, if page 6 exists but page 11
	-- doesn't, return
	-- [[Category:Random portal component with 6–10 available subpages]].
	local boundaries = {2, 6, 11, 16, 21, 26, 31, 41, 51, 101, 201, 501, 1001}
	local fragment
	for i, subpageNumber in ipairs(boundaries) do
		local subpageName = pages.subpage .. '/' .. tostring(subpageNumber)
		local subpageTitle = mw.title.new(subpageName)
		if not subpageTitle.exists then
			if i == 1 then
				fragment = string.format("less than %d", boundaries[i])
			else
				fragment = string.format("%d–%d", boundaries[i - 1], boundaries[i] - 1)
			end
			return makeSubpageTrackingCategoryLink(fragment)
		end
	end
	fragment = string.format("over %d", boundaries[#boundaries] - 1)
	return makeSubpageTrackingCategoryLink(fragment)
end

local function getRandomNumber(max)
	-- gets a random integer between 1 and max; max defaults to 1
	return mRandom.number{max or 1}
end

local function expandArg(args, key)
	-- Emulate how unspecified template parameters appear in wikitext. If the
	-- specified argument exists, its value is returned, and if not the argument
	-- name is returned inside triple curly braces.
	local val = args[key]
	if val then
		return val
	else
		return string.format('{{{%s}}}', key)
	end
end

local function getPages(args)
	local pages = {}
	pages.root = args.rootpage or currentTitle.prefixedText
	pages.subpage = pages.root .. '/' .. expandArg(args, 'subpage')
	pages.random = pages.subpage .. '/' .. getRandomNumber(args.max)
	pages.footer = 'Template:Box-footer'
	return pages
end

local function tryExpandTemplate(frame, title, args)
	local success, result = pcall(frame.expandTemplate, frame, {title = title, args = args})
	if success then
		return result
	else
		local msg = string.format(
			'<strong class="error">The page "[[%s]]" does not exist.</strong>',
			title
		)
		if isRootPortalTitle(currentTitle) then
			msg = msg .. '[[Category:Portals needing attention]]'
		end
		return msg
	end
end

local function getHeader(frame, pages, header, template)
	return tryExpandTemplate(
		frame,
		template or pages.root .. '/box-header',
		{header, pages.random}
	)
end

local function getRandomSubpageContent(frame, pages)
	return tryExpandTemplate(
		frame,
		pages.random
	)
end

local function getFooter(frame, pages, link)
	return tryExpandTemplate(
		frame,
		pages.footer,
		{link}
	)
end

function p._main(args, frame)
	frame = frame or mw.getCurrentFrame()
	local pages = getPages(args)

	local ret = {}
	ret[#ret + 1] = getHeader(frame, pages, args.header or 'subpage', args.headertemplate)
	ret[#ret + 1] = getRandomSubpageContent(frame, pages)
	if not args.footer or not args.footer:find('%S') then
		ret[#ret + 1] = '<div style="clear:both;"></div></div>'
	else
		ret[#ret + 1] = getFooter(frame, pages, string.format(
			'[[%s|%s]]',
			pages.subpage,
			expandArg(args, 'footer')
		))
	end

	return table.concat(ret, '\n') .. renderSubpageTrackingCategory(pages, args.header)
end

function p._nominate(args, frame)
	frame = frame or mw.getCurrentFrame()
	local pages = getPages(args)

	local ret = {}
	ret[#ret + 1] = getHeader(frame, pages, expandArg(args, 'header'), args.headertemplate)
	ret[#ret + 1] = getRandomSubpageContent(frame, pages)
	ret[#ret + 1] = getFooter(frame, pages, string.format(
		'[[/Nominate/%s|Suggest]] • [[%s|%s]] ',
		expandArg(args, 'subpage'),
		pages.subpage,
		args.footer or 'Archive'
	))

	return table.concat(ret, '\n') .. renderSubpageTrackingCategory(pages, args.header)
end

local function makeInvokeFunction(func)
	return function (frame)
		local args = require('Module:Arguments').getArgs(frame, {
			trim = false,
			removeBlanks = false,
			wrappers = {
				'Template:Random portal component',
				'Template:Random portal component/BHG-test',
				'Template:Random portal component with nominate'
			}
		})
		return func(args, frame)
	end
end

p.main = makeInvokeFunction(p._main)
p.nominate = makeInvokeFunction(p._nominate)

return p