본문으로 이동

모듈:Banner shell

위키백과, 우리 모두의 백과사전.

require('strict')
local p = {}
local sandbox-- = '/sandbox' -- BE SURE TO COMMENT OUT this definition when deploying to live
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' .. (sandbox or '') .. '/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

p.banner_holder = function(frame)
	local args = require('Module:Arguments').getArgs(frame, {wrappers = {'틀:배너 홀더'}})
	local image = '[[파일:' .. (args.image or 'NewFavicon icon.svg')
		.. '|' .. (args.size or '24') .. 'px'
		.. '|링크=' .. (args.image_link or '')
		.. '|alt=' .. (args.alt or '') .. ']]'
	local image_cell = mw.html.create('td')
		:addClass('mbox-image')
		:wikitext(image)
	local text_cell = mw.html.create('td')
		:addClass('mbox-text')
		:addClass('banner-shell-header')
		:tag('span')
		:addClass('nowrap')
		:css('float', 'left')
		:wikitext(string.rep(' ', 10))
		:done()
		:wikitext(args.text or 'Other talk page banners')
	local header = mw.html.create('tr')
		:node(image_cell)
		:node(text_cell)
	return shell(frame, header, args[1], yesno(args.collapsed))
end

local DuplicateBanners = function(text)
	local capture = '<span class="wpb%-project">([^<>]*)</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 cfg = mw.loadData('Module:Banner shell/config' .. (sandbox or ''))
	local args = require('Module:Arguments').getArgs(frame, {wrappers = {cfg.template}})
    
    -- 2. is_collapsed 변수를 선언하고 기본값을 지정합니다.
	local is_collapsed = false 

    -- 3. '접음' 입력값을 확인하고, args.collapsed를 설정하는 우회 로직을 바로 적용합니다.
    local input_value = args['접음']

    if input_value then
        -- 입력값을 소문자로 변환하고 '예'인지 확인합니다.
        local value = mw.text.trim(input_value):lower()
        
        if value == '예' then
            -- 템플릿 내부에서 사용될 영문 키 'collapsed'를 강제로 생성합니다.
            args.collapsed = 'yes' 
        end
    end
    
    -- args.collapsed가 설정되었는지 yesno()를 사용해 is_collapsed에 최종 값 할당
    is_collapsed = yesno(args.collapsed) or false
	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,
		dab = cfg.page_types.dab,
		sia = 'set index article',
		soft_redirect = cfg.page_types.soft_redirect,
		nonexistent = cfg.page_types.nonexistent,
		timedtext = cfg.page_types.timedtext,
		defaultns = 'extended'
	}
	local lang = mw.language.getContentLanguage()
	local classmask = require('Module:WikiProject banner' .. (sandbox or '')).class_mask
	local class = classmask(args.class or '', 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
	local blp = args.blp and args.blp:lower()
	if yesno(blp) or blp=='activepol' then
		table.insert(out, frame:expandTemplate{
			title = cfg.blp_template.blp,
			args = {activepol = blp=='activepol' and 'yes'}
		})
	elseif blp=='other' then
		table.insert(out, frame:expandTemplate{
			title = cfg.blp_template.blpo}
		)
	end
	local vital
	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/Level/' .. level
					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(cfg.vital.attention, 'L')
					end
					vital = cfg.vital.with_level:format(link, level)
				else
					vital = cfg.vital.without_level
				end
				for _, cat in ipairs(cfg.vital.categories) do
					if cat:find('_CLASS') and (class=='NA' or class=='') then
						addCategory(cfg.vital.attention, class=='NA' and 'N' or 'U')
					elseif level==nil then
						addCategory(cfg.vital.attention, 'V')
					elseif data.topic==nil then
						addCategory(cfg.vital.attention, 'T')
					else
						local category = cat
							:gsub('_CLASS', class .. '-Class')
							:gsub('_LEVEL', level)
							:gsub('_TOPIC', data.topic)
						addCategory(category)
					end
				end
				addCategory(cfg.vital.all)
			else
				addCategory(cfg.vital.not_listed)
			end
		end
	end

    local ns_map = {
    ['사용자'] = '사용자 문서',            -- 'user page' 대신 '사용자 문서'
    ['사용자토론'] = '사용자 문서',        -- 'user page' 대신 '사용자 문서'
    ['틀'] = '틀 문서',
    ['틀토론'] = '틀 문서',
    ['문서'] = '프로젝트 문서',            -- 'project page' 대신 '프로젝트 문서'
    ['문서토론'] = '프로젝트 문서',
    ['파일'] = '파일 문서',
    ['파일토론'] = '파일 문서',
    ['분류'] = '분류 문서',
    ['분류토론'] = '분류 문서',
    ['포털'] = '포털 문서',
    ['포털토론'] = '포털 문서',
    ['초안'] = '초안 문서',             -- 'draft' 대신 '초안 문서'
    ['초안토론'] = '초안 문서',          -- 'draft' 대신 '초안 문서'
    ['모듈'] = '모듈 문서',
    ['모듈토론'] = '모듈 문서',
    ['도움말'] = '도움말 문서',           -- 'help page' 대신 '도움말 문서'
    ['도움말토론'] = '도움말 문서',
    ['위키백과'] = '프로젝트 문서',
    ['위키백과토론'] = '프로젝트 문서',
    ['미디어위키'] = '인터페이스 문서',
	['미디어위키토론'] = '인터페이스 문서',
    ['행사'] = '문서',
    ['행사토론'] = '문서',
    ['토론'] = '문서',                  -- 메인 네임스페이스의 토론 페이지를 위해 추가
}
	local nsText = title.nsText
	local normalized_ns = ns_map[nsText] or nsText

	local text, icon_image, icon_str
	if class=='NA' then
    icon_image = cfg.icons.type[normalized_ns] or cfg.icons.default
    icon_str = lang:ucfirst(normalized_ns)
    text = {cfg.rating.not_required:format(vital or normalized_ns)}
	elseif class=='' then
		icon_image = cfg.icons.unassessed
		icon_str =  'Unassessed article'
		text = {cfg.rating.not_yet:format(vital or pagetype)}
		addCategory('All unassessed articles')
	else
		icon_image = cfg.icons.quality[class] or cfg.icons.unassessed
		icon_str =  class .. '-Class ' .. pagetype
		text = {cfg.rating.rated:format(vital or pagetype, class)}
		frame:preprocess('{{#assessment:Project-independent assessment' .. '|' .. class .. '}}')
	end
	local icon = string.format('[[File:%s|%s|35px|class=noviewer|alt=]]', icon_image, icon_str)
	table.insert(text, ' ' .. cfg.rating.scale)
	if args[1] then
		table.insert(text, '<br>' .. cfg.project.interest .. ' ')
		table.insert(text, is_collapsed and cfg.project.collapsed or cfg.project.uncollapsed)
		local duplicate_cat = DuplicateBanners(args[1])
		if duplicate_cat and title.isTalkPage then
			addCategory(cfg.tracking.duplicate, duplicate_cat)
		end
	elseif not yesno(args.vital) and class~='' then -- if no projects and not vital and assessed then add class super category
		addCategory(class .. '-Class ' .. (class=='NA' and 'pages' or 'articles'))
	end
	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(table.concat(text))
			:done()
	table.insert(
		out,
		shell(frame, header, args[1], is_collapsed, 'wpbs')
	)
	if args.listas then
		table.insert(out, frame:preprocess('{{DEFAULTSORT:' .. args.listas .. '}}'))
	end
	if not demo then
		local tracking = require('Module:Check for unknown parameters')._check({
			unknown = cfg.tracking.unknown,
			preview = cfg.tracking.preview,
			'1', 'blp', 'category', 'class', 'collapsed', 'demo_page', 'listas', 'vital', '접음'
		}, frame:getParent().args)
		table.insert(out, tracking)
		if args.category and yesno(args.category)~=false then -- category should not be "yes"
			addCategory(cfg.tracking.invalid, 'category')
		end
		if args.collapsed and yesno(args.collapsed)~=true then -- collapsed should not be "no"
			addCategory(cfg.tracking.invalid, 'collapsed')
		end
		if yesno(blp)==nil and blp~=nil and blp~='other' and blp~='activepol' then
			addCategory(cfg.tracking.invalid, 'blp')
		end
		if pagetype=='article' and args.class and class=='' then -- find pages with invalid class parameter
			addCategory(cfg.tracking.invalid, 'Zclass')
		end
	end
	return table.concat(out)
end

return p