モジュール:Information

2020年1月8日 (水) 19:37時点におけるWikiSysop (トーク | 投稿記録)による版 (1版 をインポートしました)

このモジュールについての説明文ページを モジュール:Information/doc に作成できます

--[[  
  __  __           _       _        ___        __                            _   _             
 |  \/  | ___   __| |_   _| | ___ _|_ _|_ __  / _| ___  _ __ _ __ ___   __ _| |_(_) ___  _ __  
 | |\/| |/ _ \ / _` | | | | |/ _ (_)| || '_ \| |_ / _ \| '__| '_ ` _ \ / _` | __| |/ _ \| '_ \ 
 | |  | | (_) | (_| | |_| | |  __/_ | || | | |  _| (_) | |  | | | | | | (_| | |_| | (_) | | | |
 |_|  |_|\___/ \__,_|\__,_|_|\___(_)___|_| |_|_|  \___/|_|  |_| |_| |_|\__,_|\__|_|\___/|_| |_|
                                                                                               
This module is intended to be the engine behind "Template:Information".

Please do not modify this code without applying the changes first at
"Module:Information/sandbox" and testing at "Module:Information/testcases".

Authors and maintainers:
* User:Jarekt - original version 
]]
local ISOdate = require('Module:ISOdate')

-- ====================================================================
local function langWrapper(text, textLang, userLang) 
-- code equivalent to https://commons.wikimedia.org/wiki/Template:Description
	local dir = mw.language.new( textLang ):isRTL() and 'rtl' or 'ltr'   
	local str = string.format('<span class="language %s"><b>%s:</b></span>', textLang, mw.language.fetchLanguageName( userLang, textLang  ))
    return string.format('<div class="description mw-content-%s" dir="%s" lang="%s">%s %s</div>', dir, dir, textLang, str, text)
end

-- ====================================================================
-- === This function is just responsible for producing HTML of the  ===
-- === template. At this stage all the fields are already filed     ===
-- ====================================================================
local function Build_html(args)
	-- Permissions tag
	local tag1 = mw.message.new( "wm-license-information-permission" ):inLanguage(args.lang):plain()
	local tag2 = mw.message.new( "wm-license-information-permission-reusing-link" ):inLanguage(args.lang):plain()
	local tag3 = mw.message.new( "wm-license-information-permission-reusing-text" ):inLanguage(args.lang):plain()
	local permission_tag  = string.format("%s<br /><small>([[%s|%s]])</small>", tag1, tag2, tag3)
	local dir  = mw.language.new( args.lang ):isRTL() and 'rtl' or 'ltr'    -- get text direction
	tag1 = mw.message.new( "wm-license-information-description" ):inLanguage(args.lang):plain()
	tag2 = mw.title.getCurrentTitle().text -- pagename
	local description_tag = string.format('%s<span class="summary fn" style="display:none">%s</span>', tag1, tag2)
	tag3 = string.format(' lang="%s"', args.lang)

	-- add other fields
	local params = {
		{field='description'    , id='fileinfotpl_desc'  , tag=description_tag,                  alt=true, wrapper='\n%s', td=' class="description"'},
		{field='other_fields_1'},
		{field='date'           , id='fileinfotpl_date'  , tag='wm-license-information-date',              wrapper='\n%s', td=tag3},
		{field='source'         , id='fileinfotpl_src'   , tag='wm-license-information-source',  alt=true, wrapper='\n%s'}, 
		{field='author'         , id='fileinfotpl_aut'   , tag='wm-license-information-author',  alt=true, wrapper='\n%s'},
		{field='permission'     , id='fileinfotpl_perm'  , tag=permission_tag,                             wrapper='\n%s'},
		{field='other_versions' , id='fileinfotpl_ver'   , tag='wm-license-information-other-versions',    wrapper='\n%s'}, 
		{field='other_fields'}
	}
	local results = {}
	for _, param in ipairs(params) do
		local field, tag, cell1, cell2, id
		field = args[param.field]
		if field and mw.ustring.match(field,"^[%s%p]+$") then field=nul; end -- ignore punctuation only fields

		if param.id then -- skip "other fields" parameter
			if field then  -- add "id" to first <td> cell only if the field is present
				id = string.format('id="%s" ', param.id)
			elseif param.alt then -- Some field have "Missing" message if field is not provided
				-- code equivalent to Template:Source missing, Template:Author missing, Template:Description missing
				tag1  = 'class="boilerplate metadata" id="cleanup" style="text-align: center; background: #ffe; '..
					'margin: .75em 15%; padding: .5em; border: 1px solid #e3e3b0;'
				tag2  = mw.message.new( 'wm-license-information-'..param.field..'-missing' ):inLanguage(args.lang):plain()
				tag3  = mw.message.new( 'wm-license-information-'..param.field..'-missing-request' ):inLanguage(args.lang):plain()
				field = string.format('<div %s direction: %s;" lang="%s">%s\n%s\n</div>', tag1, dir, args.lang, tag2, tag3)
			end
			if field or args.demo then  -- skip the row if still no field
				tag = param.tag
				if string.sub(tag,1,10) == 'wm-license' then
					tag = mw.message.new( tag ):inLanguage(args.lang):plain() -- label message in args.lang language
				end
				cell1 = string.format('<td %sclass="fileinfo-paramfield" lang="%s">%s</td>\n', id or '', args.lang, tag)
				cell2 = string.format('<td%s>'.. param.wrapper ..'</td>', param.td or '', field or '')
				field = string.format('<tr style="vertical-align: top">\n%s%s\n</tr>\n\n', cell1, cell2)
			end
		end
		table.insert(results, field)
	end

	-- add table and outer layers
	local style = string.format('class="fileinfotpl-type-information toccolours vevent '..
		'mw-content-%s" style="width: 100%%; direction: %s;" cellpadding="4"', dir, dir)
	results = string.format('<table %s>\n\n%s\n</table>\n', style, table.concat(results))
	results = string.format('<div class="hproduct commons-file-information-table">\n%s\n</div>', results)
	return results
end

-- ==================================================
-- === External functions ===========================
-- ==================================================
local p = {}

-- ===========================================================================
-- === Version of the function to be called from other LUA codes
-- ===========================================================================
function p._information(args)

	local cats = ''
	
	-- ============================================================================================
	-- === add [[Category:Pages using Information template with incorrect parameter]] if needed ===
	-- ============================================================================================
	local page = mw.title.getCurrentTitle()
	local namespace = page.namespace   -- get page namespace
	if namespace==6 or namespace==10 then
		local allowedFields = {'description', 'date', 'permission', 'author', 'other_versions',  
				'source','other_fields', 'other_fields_1', 'demo', 'lang', 'mid', 'pageid'}
		local set, badField = {}, {}
		for _, field in ipairs(allowedFields) do set[field] = true end
		for field, _ in pairs( args ) do 
			if not set[field] then
				table.insert(badField, field)
			end
		end
		if #badField>0 then
			cats = string.format('\n;<span style="color:red">Error in [[Template:Information|{{Information}}'..
				' template]]: unknown parameter "%s".</span>',  table.concat(badField,'", "'))
			cats = cats .. '\n[[Category:Pages using Information template with incorrect parameter]]'
		end
	end
	if namespace==6  then -- files are required to have at least the 3 fields below
		local reqFields = {description='Media lacking a description', author='Media lacking author information', source='Images without source'}
		for field, errCat in pairs(reqFields) do 
			if not args[field] then
				cats = cats .. '\n[[Category:'.. errCat ..']]'				
			end
		end
	end


	-- ====================================================
	-- === harvest structured data                      === 
	-- ====================================================
	-- at the moment we only harvest caption from SDC to use in case description is missing
	if namespace==6 and not args.description then -- file namespace
		local entity = nil
		if page.id>0 then -- some pages sometimes have pageid = 0
			entity = mw.wikibase.getEntity("M" .. page.id)
		end
		if entity then 
			-- build language fallback list (snipit borrowed from (Module:Wikidata label]])
			args.lang = string.lower(args.lang) or 'en'
			local langList = mw.language.getFallbacksFor(args.lang)
			table.insert(langList, 1, args.lang)
			
			-- get label in users language or one of that language fallback list
			for _, language in ipairs(langList) do  -- loop over language fallback list looking for label in the specific language
				args.description = entity:getLabel(language) 
				--args.description = langWrapper(args.description, language, args.lang) -- disable for time being as labels sometimes have wrong language codes
				if args.description then 
					break -- label found and we are done
				end  
			end
		end
	end 
	
	-- ====================================================
	-- === add tag templates used for tracking          === 
	-- ====================================================
	local frame = mw.getCurrentFrame()
	-- add the template tag (all official infoboxes transclude {{Infobox template tag}} so files without that tag do not have an infobox
	frame:expandTemplate{ title = 'Infobox template tag' } 
	if args.date then
		-- apply ISODate to function to date string to convert date in ISO format to translated date string
		args.date = ISOdate._ISOdate(args.date, args.lang, '', 'dtstart', '100-999')      
	end 
	return Build_html(args) .. cats
end

-- ===========================================================================
-- === Version of the function to be called from template namespace
-- ===========================================================================
function p.information(frame)
	-- switch to lowercase parameters to make them case independent
	local args = {}
	for name, value in pairs( frame:getParent().args ) do 
		if value ~= '' then -- nuke empty strings
			local name1 = string.gsub( string.lower(name), ' ', '_')
			args[name1] = value
		end
	end
	for name, value in pairs( frame.args ) do 
		if value ~= '' then -- nuke empty strings
			local name1 = string.gsub( string.lower(name), ' ', '_')
			args[name1] = value
		end
	end
		
	if not (args.lang and mw.language.isSupportedLanguage(args.lang)) then 
		args.lang = frame:callParserFunction( "int", "lang" ) -- get user's chosen language
	end
	
	-- call the inner "core" function
	return p._information(args)	
end

return p