Permanently protected module

Module:Banner shell

From the AARoads Wiki: Read about the road before you go
Jump to navigation Jump to search
local p = {}
local yesno = require('Module:Yesno')

local shell = function(frame, header, content, collapsed, class)
	local styles = frame:extensionTag('templatestyles', '', {src = 'Module:Message box/tmbox.css'})
		.. frame:extensionTag('templatestyles', '', {src = 'Module:Banner shell/styles.css'})
	local content_row
	if content then
		content_row = mw.html.create('tr')
			:tag('td')
			:attr('colspan', '2')
			:addClass('banner-shell-inner'):addClass('outercollapse')
			:wikitext(content)
			:done()
	end
	local holder = mw.html.create('table')
		:attr('role', 'presentation')
		:addClass('tmbox'):addClass('tmbox-notice'):addClass('banner-shell')
		:addClass(class) -- allow additional class to be specified
		:addClass(content and 'mw-collapsible' or nil)
		:addClass(collapsed and 'mw-collapsed' or nil)
		:node(header)
		:node(content_row)
	return styles .. tostring(holder)
end

local DuplicateBanners = function(text)
	local capture = '<span class="wpb%-project">([%w%s]*)</span>'
	local banners = {}
	for project in text:gmatch(capture) do
		if banners[project] == true then
			return project
		end
		banners[project] = true
	end
end

p.banner_shell = function(frame)
	local args = require('Module:Arguments').getArgs(frame, {wrappers = {'Template:WikiProject banner shell', 'Template:Talk header'}})
	local title = args.demo_page and mw.title.new(args.demo_page) or mw.title.getCurrentTitle()
	local pagetype = require('Module:Pagetype')._main{
		page = title.prefixedText,
		[1] = args.class,
		dab = 'disambiguation page',
		draft = 'draft page',
		soft_redirect = 'soft redirect',
		translate = 'translation draft page',
		defaultns = 'extended'
	}
	local classmask = require('Module:WikiProject banner').class_mask
	
	local class = pagetype=='article' and args.class or pagetype=='file' and args.class or ''
	class = classmask(class, title.talkPageTitle, false, pagetype)
	local demo = not yesno(args.category or true, true) or args.demo_page
	local out = {}
	local addCategory = function(category, sort_key)
		if not demo and title.isTalkPage then
			local category_title = mw.title.new('Category:' .. category)
			table.insert(out, '[[' .. category_title.prefixedText .. (sort_key and ('|' .. sort_key) or '') .. ']]')
		end
	end
	if demo and not args.demo_page then
		pagetype = 'article'
	end
	if class=='' and args[1] then -- check if class parameters are defined by any project banner
		local articleclass = require('Module:WikiProject banner').readarticleclass(
			{ignore_blank = true, only_subtemplates = true},
			title.talkPageTitle.prefixedText
		)
		if articleclass~='' then -- class parameters are defined by one or more project banners
			class = nil -- no global assessment
			local raw_args = require('Module:Arguments').getArgs(frame, {
				wrappers = {'Template:WikiProject banner shell', 'Template:Talk header'},
				removeBlanks = false
			})
		end
	end
	local class2 = class and class~='' and (class .. '-Class') or 'Unassessed'
	local vital
	local icon_class = 'council'
	if yesno(args.vital) then
		local page = mw.ustring.upper(mw.ustring.sub(title.subjectPageTitle.text, 1, 1)) -- get first letter of article name
		local codepoint = mw.ustring.codepoint(page, 1, 1)
		if codepoint<65 or codepoint>90 then --first letter is not between A-Z
			page = 'others'
		end
		local data_page = mw.title.new('Wikipedia:Vital articles/data/' .. page .. '.json')
		if data_page.exists then
			local index = title.subjectPageTitle.text
			index = tostring(tonumber(index))==index and tonumber(index) or index --convert to number if page is numerical, otherwise loadJsonData does not work
			local data = mw.loadJsonData(data_page.fullText)[index]
			if data then
				local level = data.level and tostring(data.level)
				if level and data.topic then
					local link = 'Wikipedia:Vital articles'
					if level~='3' then
						link = link .. '/Level/' .. level
					end
					if (level=='4' or level=='5') then
						link = link .. '/' .. data.topic
					end
					if data.sublist then
						link = link .. '/' .. data.sublist
					end
					if data.section then
						link = link .. '#' .. data.section
					end
					if not mw.title.new(link).exists then -- add tracking category if link does not exist
						addCategory('Wikipedia vital articles needing attention', 'L')
					end
					vital = 'This [[File:Círculos Concéntricos.svg|16px|link=|alt=]]&nbsp;<b>[[' .. link .. '|level-' .. level .. ' vital article]]</b> '
				else
					vital = 'This vital article '
				end
				local vitalCat = function(cat, valid) -- valid is table of 3 booleans for class/level/topic, if true then category will not be populated unless valid
					local show_cat = true
					if (valid.class and (class=='NA' or class==nil or class==''))
						or (valid.level and level==nil)
						or (valid.topic and data.topic==nil) then
						show_cat = false
					end
					if show_cat then
						local category = cat:gsub('_CLASS', class2)
							:gsub('_LEVEL', level or 'unknown')
							:gsub('_TOPIC', data.topic or 'an unknown topic')
						addCategory(category)
					end
				end
				vitalCat('_CLASS vital articles', {})
				vitalCat('Wikipedia level-_LEVEL vital articles', {})
				vitalCat('Wikipedia vital articles in _TOPIC', {})
				vitalCat('_CLASS level-_LEVEL vital articles', {class=true, level=true})
				vitalCat('Wikipedia level-_LEVEL vital articles in _TOPIC', {level=true, topic=true})
				vitalCat('_CLASS vital articles in _TOPIC', {class=true, topic=true})
			else
				addCategory('Articles not listed in the vital article list')
			end
		end
	end
	local pagetype_display = pagetype=='article' and 'article'
		or pagetype=='page' and 'page'
		or ('<b>' .. pagetype .. '</b>')-- use bold if page type is not article
	local text = vital or 'This ' .. pagetype_display .. ' '
	if class or not args[1] then
		local icons = { -- map output of pagetype function to input of class icon function
			['project page'] = 'project',
			['user page'] = 'user',
			['interface page'] = 'interface',
			['help page'] = 'help',
			['module'] = 'module',
			['disambiguation page'] = 'disambig',
			['draft page'] = 'draft',
			['redirect'] = 'redirect',
			['soft redirect'] = 'redirect',
			['translation draft page'] = 'translate',
			['page'] = 'na'
		}
		icon_class = class or class=='NA' and (icons[pagetype] or pagetype)
		if class=='' then
			text = text .. 'has not yet been rated'
		elseif class=='Annex' or class=='Disambig' or class=='Draft' or class=='File' or class=='Module' or class=='Project' or class=='Redirect' or class=='Template' or class=='Translate' or class=='NA' then
			text = text .. 'does not require a rating'
		elseif class=='AM' then
			text = text .. 'is rated <span style="font-weight:bold;">' .. class .. '-class</span>'
		else
			text = text .. 'is rated <span style="font-weight:bold;">' .. class .. '-class</span>'
		end
		text = text .. ' on the AARoads Wiki\'s [[AARoads:Assessment|content assessment]] scale.' .. frame:expandTemplate{title = 'Template:Banner/AARoads Wiki', args = { demo_page = '' }} 
		if args[1] then
			text = text .. '<br>It'
		elseif not yesno(args.vital) then
			addCategory(class2 .. ' articles')
		end
	end
	if args[1] then
		text = text .. ' falls under ' .. (yesno(args.collapsed)
			and 'multiple topics.'
			or ('the following topics:')
		)
	end
	local icon = require('Module:Class')._icon{icon_class, size='35px'}
	local header = mw.html.create('tr')
		:tag('td'):addClass('assess'):wikitext(icon):done()
		:tag('td'):addClass('banner-shell-header'):css('text-align', 'left'):css('font-weight', 'normal'):wikitext(text):done()
	table.insert(
		out,
		shell(frame, header, args[1], yesno(args.collapsed), 'wpbs')
	)
	if args[1] then
		local duplicate_cat = DuplicateBanners(args[1])
		if duplicate_cat and title.isTalkPage then
			addCategory('Pages using WikiProject banner shell with duplicate banner templates', duplicate_cat)
		end
	end

	local prefix
		if title.namespace == 7 then
			prefix = 'ƒ'
		elseif title.namespace == 11 then
			prefix = '†'
		elseif title.namespace == 103 then
			prefix = 'Д'
		elseif title.namespace == 105 then
			prefix = 'Т'
		elseif title.namespace == 829 then
			prefix = 'μ'
		else 
			prefix = ''
		end
			
	if args.listas or args.sort then
		local sort = args.listas or args.sort
		table.insert(out, frame:preprocess('{{DEFAULTSORT:' .. prefix .. sort .. '}}'))
		else
		table.insert(out, frame:preprocess('{{DEFAULTSORT:' .. prefix .. title.text .. '}}'))
	end
	if not demo then
		local tracking = require('Module:Check for unknown parameters')._check({
			['unknown']='[[Category:Pages using WikiProject banner shell with unknown parameters|_VALUE_ ]]',
			['preview']='Page using [[Template:WikiProject banner shell]] with unknown parameter "_VALUE_"',
			'1', 'category', 'class', 'collapsed', 'demo_page', 'listas', 'sort', 'country', 'state', 'province', 'variant', 'acr', 'bcr', 'reassess', 'attention', 'needs-infobox', 'attention-map', 'needs-map', 'attetion-rjl', 'needs-jctint', 'missing-rjl', 'bulleted-rjl', 'needs-shield', 'photo', 'image'
		}, frame:getParent().args)
		table.insert(out, tracking)
		for _, param in ipairs{'activepol', 'blp', 'blpo', 'category', 'collapsed', 'living'} do
			if yesno(args[param], 'invalid')=='invalid' then
				addCategory('Pages using WikiProject banner shell with invalid parameters', param)
			end
		end
		if pagetype=='article' and args.class and class=='' then -- find pages with invalid class parameter
			addCategory('Pages using WikiProject banner shell with invalid parameters', 'Zclass')
		end
	end
	return table.concat(out)
end

return p