Module:Class mask

From OODA WIKI

This module implements {{class mask}}. See the template page for documentation.

Quality function

This "quality" function implements the logic needed for OODA WIKI:Village pump (proposals)/Archive 198#Project-independent quality assessments.

The module takes a project-defined class |class= and a banner-defined class (tested via |article_class=) and normalises the output. The result is prefixed by a letter as follows:

  • H: the project class is not defined, or it is defined and equals the article class. In this case WPBannerMeta will hide the display of the quality assessment (categorisation will still happen as usual).
  • X: the project class and article class differ, so the tracking category Category:Articles with conflicting quality ratings will be populated.
  • Y: the project class is defined and the article class is undefined or invalid. The quality assessment is displayed as usual in the project banner.

This function is tested at Module talk:Class mask/testcases2.


local p = {}

local isarticle = function(class)
	local nonarticleclasses = {'Template', 'File', 'Category', 'Disambig', 'Redirect', 'Portal', 'Project', 'Draft', 'Book', 'FM'} -- these classes will not be identified as conflicting with NA-class
	local article = true
	for _,v in ipairs(nonarticleclasses) do
		if class==v then -- class matches one of the non-article classes
			article = false
			break
		end
	end
	return article
end

local ucfirst = function(s)
	-- Returns the given string with the first character in upper case.
	-- Should not be used with non-ascii strings.
	return s:sub(1, 1):upper() .. s:sub(2, -1)
end

local resolveFQSgrade = function(grade, args)
	if (args[grade] or args.FQS)=='yes' then
		return ucfirst(grade)
	else
		return 'NA'
	end
end

p._main = function(args, title)
	title = title or mw.title.getCurrentTitle()
	local out = ''
	local grade = args[1]
	if not grade or grade=='¬' then -- undefined
		out = '¬'
	else
		local ns = title.namespace
		grade = grade:match('^%s*(.-)%s*$'):lower()
		if title.subjectPageTitle.isRedirect then
			out = resolveFQSgrade('redirect',args)
		elseif ns==1 then -- Talk
			if require('Module:Disambiguation').isDisambiguation(title.subjectPageTitle:getContent()) then
				out = resolveFQSgrade('disambig',args)
			else
				if grade=='start' or grade=='stub' then -- Ucfirst
					if args[grade]~='no' then
						out = ucfirst(grade)
					end
				elseif grade=='b' or grade=='c' or grade=='fa' or grade=='fl' or grade=='a' or grade=='ga' then -- Upper-case
					if args[grade]~='no' then
						out = grade:upper()
					end
				elseif args[grade:upper()] then -- Upper-case syntax
					out = args[grade:upper()]
				elseif args[grade:lower()]=='yes' then -- Lower-case syntax
					out = mw.language.getContentLanguage():ucfirst(grade:lower())
				elseif grade=='list' or grade=='sia' or grade=='si' or grade=='sl' then-- List
					if args['list']~='no' then
						out = 'List'
					end
				elseif grade=='dab' or grade=='disambig' or grade=='disambiguation' or grade=='disamb' then
					out = resolveFQSgrade('disambig', args)
				end
			end
		elseif ns==7 or ns==711 then -- File talk
			if grade=='fm' and (args.fm or args.FQS)=='yes' then
				out = 'FM'
			else
				out = resolveFQSgrade('file', args)
			end
		elseif ns==15 then -- Category talk
			out = resolveFQSgrade('category', args)
		elseif ns==101 then -- Portal talk
			out = resolveFQSgrade('portal', args)
		elseif ns==11 or ns==829 then -- Template talk
			out = resolveFQSgrade('template', args)
		elseif ns==5 then -- Wikipedia talk
			out = resolveFQSgrade('project', args)
		elseif ns==119 then -- Draft talk
			out = resolveFQSgrade('draft', args)
		elseif ns==13 and args['help']=='yes' then -- Help talk
			out = 'Help'
		elseif ns==3 and args['user']=='yes' then -- User talk
			out = 'User'
		else
			out = 'NA'
		end
	end
	return out
end

p.main = function(frame)
	local getArgs = require('Module:Arguments').getArgs
	local args = getArgs(frame, {
		removeBlanks = false,
		wrappers = 'Template:Class mask'
	})
	return p._main(args)
end

local getclass = function(args, title)
	local class = '¬'
	if args.QUALITY_SCALE == 'inline' then
		class = args.class
	elseif args.QUALITY_SCALE == 'subpage' then
		if mw.title.new(args.BANNER_NAME..'/class').exists then
			local frame = mw.getCurrentFrame()
			class = frame:expandTemplate{title = args.BANNER_NAME..'/class', args = args}
		end
	else
		args.FQS = (args.QUALITY_SCALE == 'extended') and 'yes' or 'no'
		args[1] = args.class
		class = p._main(args, title)
	end
	return class
end

p.readarticleclass = function(options, page) -- used by p._quality and Module:Banner shell
	page = page or mw.title.getCurrentTitle().prefixedText
	local get_parameter_value = require("Module:Template parameter value").getValue
	local WPBSredirects = {'WikiProject banner shell','WikiProject banner shell/sandbox','Bannershell','Multiple wikiprojects','Project shell','Scope shell','WPB','WPBS','WPBannerShell','WP Banner Shell','WP banner shell','WikiProjectBannerShell','WikiProjectBanner Shell','WikiProjectBanners','WikiProject BannerShell','WikiProject Banner Shell','WikiProject Banners','WikiProject Banners Shell','WikiProject Shell','WikiProject banner','WikiProject banner shell/redirect','WikiProject shell','WikiprojectBannerShell','Wikiproject banner holder','Wikiproject banner shell','Wikiprojectbanners','Wikiprojectbannershell','Wpb','Wpbannershell','Wpbsgclass'}
	local success, result = get_parameter_value(page, WPBSredirects, "class", options)
	return success and result
	-- returns FALSE if banner shell template does not exist on page
	-- returns BLANK if class parameter is not defined or is defined blank
	-- otherwise returns class parameter
end

p._quality = function(args)
	local title = args.page and mw.title.new(args.page) or mw.title.getCurrentTitle()
	local local_class = getclass(args, title)
	local prefix, class = 'Y', local_class
	if local_class=='¬' then
		class = '¬'
	elseif args.QUALITY_CRITERIA ~= 'custom' then -- project uses standard scale and will inherit article class if needed
		local article_class = p.readarticleclass({ignore_subtemplates=true},title.prefixedText)
		article_class = article_class and p._main({article_class}, title)
		if article_class then -- banner shell exists
			if article_class == '' then -- no article class defined
				if local_class == '' then -- local class also does not exist, check whether any other class parameters are defined inside the shell
					local classparam = p.readarticleclass({ignore_blank=true, only_subtemplates=true},title.prefixedText)
					if classparam == '' then -- no class parameters defined, display as globally unassessed
						prefix = 'H' -- hide quality class in project banner
					end
				end
			elseif local_class == '' or local_class == article_class then -- local class matches article class or is blank
				prefix = 'H' -- hide quality class in project banner
				class = article_class
			elseif (article_class == 'NA') and not isarticle(local_class) then -- article class and local class are both non-article classes
				prefix = 'H'
			else -- article class exists and differs from local class
				prefix = 'X' -- X will indicate to meta banner that classes are different, so trigger a tracking category
			end
		end
	end
	return (args.noprefix and '' or prefix) .. class
end

p.quality = function(frame) -- used by WPBM to check global quality and compare with local parameter
	return p._quality(frame.args)
end

return p