Module:Transclusion Arguments

local p = {}

local utilsArg = require("Module:UtilsArg") local utilsCargo = require("Module:UtilsCargo") local utilsTable = require("Module:UtilsTable")

local TABLE = "TransclusionArguments" local TABLE_LINK = "Special:CargoTables/"..TABLE..""

function p.Main(frame) local utilsLayout = require("Module:UtilsLayout") local utilsMarkup = require("Module:UtilsMarkup") local utilsTable = require("Module:UtilsTable")

local args = utilsArg.parse(frame:getParent.args, p.Templates.Arguments) if args.isValid then args.isValid = args.isValid == "yes" end local limit = args.limit and tonumber(args.limit) args.limit = nil

local arguments = p.query(args) local allPages = utilsTable.map(arguments, "_pageName") allPages = utilsTable.unique(allPages) arguments = utilsTable.groupBy(arguments, "argument") arguments = utilsTable.mapValues(arguments, utilsTable._map("_pageName")) arguments = utilsTable.mapValues(arguments, utilsTable.unique) local rows = {} for argument, pages in pairs(arguments) do		argument = " " local pageLinks = utilsTable.map(pages, utilsMarkup.link) local pageList = table.concat(pageLinks, " • ") table.insert(rows, {argument, #pages, pageList}) end -- sort descending by # of pages then ascending by argument value table.sort(rows, function(a, b)		if a[2] == b[2] then			return a[1] < b[1]		else			return a[2] > b[2]		end	end) if limit then rows = utilsTable.take(rows, limit) end local purgeLink = mw.title.getCurrentTitle:fullUrl({		action = "purge"	}) local purgeButton = string.format(' &lsqb;[%s purge]&rsqb; ', purgeLink)

local wikitable = utilsLayout.table({		caption = string.format(' Total pages: %d %s ', #allPages, purgeButton),		headers = {args.header or args.parameter, "Page Count", "Pages"},		rows = rows,		sortable = true,	}) return wikitable end

function p.fetchTransclusions(args) local limit = args.limit local template = args.template local paramLookup = utilsTable.invert(args.parameters)

local arguments = p.query({		template = args.template,		_pageName = args._pageName	}) arguments = utilsTable.filter(arguments, function(argument)		return paramLookup[argument.parameter]	end) arguments = utilsTable.groupBy(arguments, "parameter") arguments = utilsTable.toArray(arguments) local transclusions = utilsTable.zip(arguments)

for i, transclusion in ipairs(transclusions) do		if limit and i > limit then break end utilsTable.merge(transclusion, transclusion[1] or nil) transclusion.pageInstance = nil transclusion.parameter = nil transclusion.argument = nil transclusion.arguments = {} transclusion.isValid = true for i, argument in ipairs(transclusion) do			local isValid = argument.isValid == "1" if not isValid then transclusion.isValid = false end transclusion.arguments[argument.parameter] = { value = argument.argument, isValid = isValid }			transclusion[i] = nil end end return transclusions end

function p.query(args) local isValid = args.isValid if isValid ~= nil then isValid = isValid and "1" or "0" end local rows = utilsCargo.query(TABLE, "_pageName, template, module, pageInstance, parameter, argument, isValid", {		where = utilsCargo.allOf({ template = args.template, module = args.module, _pageName = args._pageName, pageInstance = args.pageInstance, parameter = args.parameter, argument = args.argument, isValid = isValid, }),		limit = args.limit or 5000,	}) return rows end

function p.store(transclusion) return utilsArg.store(transclusion) end

p.Templates = { ["Arguments"] = { format = "block", purpose = string.format("Uses %s to construct a table that identifies which pages use a certain template with certain arguments.", TABLE_LINK), usesData = true, paramOrder = {"template", "parameter", "header", "argument", "isValid", "limit"}, params = { template = { required = true, desc = "A template name.", type = "wiki-template-name", trim = true, },			parameter = { required = true, desc = "A parameter name for the given template.", type = "string", trim = true, },			header = { required = true, desc = "A header value for the resulting table.", trim = true, },			argument = { desc = "A specific argument value to query for, if desired.", type = "string", },			isValid = { desc = "If empty, the query will be for all arguments. If, only valid arguments are included. If  , only invalid arguments are included.", enum = {"yes", "no"}, trim = true, nilIfEmpty = true, },			limit = { desc = "Limits the number of rows in the generated table.", default = 5000, trim = true, },		},		examples = { {				desc = "Pages using ", args = { template = "Template:Icon", parameter = "1", header = "Color Name", argument = "TWWHD Eighth Note", },			},			{				desc = "Category:Articles using invalid icon names", args = { template = "Template:Icon", parameter = "1", header = "Icon Code", isValid = "no", limit = "3", },			},		}	},	["Arguments/Store"] = { purpose = "Stores data regarding template/module usage for the benefit of Template:Arguments.", storesData = true, categories = {"Metatemplates"}, paramOrder = {"template", "module", "pageInstance", "parameter", "argument", "isValid"}, params = { template = { desc = "The template being used.", type = "wiki-template-name", },			module = { desc = "The module being used.", type = "wiki-page-name", },			pageInstance = { desc = "Specifies the instance of the template, when a template is used multiple times on a page.", type = "number", },			parameter = { desc = "A parameter name.", type = "string", },			argument = { desc = "The value of the argument corresponding to .", type = "string", },			isValid = { desc = " or   if the argument is valid,   or   if it is not valid.", enum = {"1", "0", "yes", "no"}, },		}	} }

function p.Schemas return { fetchTransclusions = { args = { type = "record", required = true, properties = { {						name = "template", required = true, type = "string", desc = "The template name to fetch tranclusions for.", },					{						name = "parameters", required = true, type = "array", items = { type = "string" }, desc = "List of template parameters to include in the returned data. Currently, only required parameters are supported.", },					{						name = "limit", type = "number", desc = "The number of transclusions to return." },				},			},		},		store = { transclusion = { type = "record", required = true, properties = { {						name = "module", desc = "A module name. Defaults to .", },					{						name = "args", desc = "Template/module arguments.", type = "map", keys = { oneOf = { {									type = "string" },								{									type = "number" },							},						},						values = { type = "string" }, },					{						name = "isValid", type = "boolean", desc = "Indicates whether or not the template transclusion or module function call is valid.", },				},			},		},	} end

function p.Documentation return { fetchTransclusions = { params = {"args"}, returns = "A list of tranclusions.", cases = { {					args = { {							template = "Template:Transcript Copy", parameters = {"fromPage", "storedAs"}, }					}				},			},		},		query = { params = {"args"}, returns = string.format("Data from %s.", TABLE_LINK), cases = { {					desc = "Category:Articles using invalid color names", args = { {							template = "Template:Color", isValid = false, limit = 3, },					},				},			},		},		store = { desc = string.format("Stores data in %s.", TABLE_LINK), params = {"transclusion"}, returns = nil, cases = { {					args = { {							module = "Module:Arguments", isValid = true, args = { [1] = "foo", bar = "baz", },						},					},				},			},		},	} end

return p