Module:Information: Difference between revisions
From Research Realm
No edit summary |
No edit summary |
||
Line 2: | Line 2: | ||
__ __ _ _ ___ __ _ _ | __ __ _ _ ___ __ _ _ | ||
| \/ | ___ __| |_ _| | ___ _|_ _|_ __ / _| ___ _ __ _ __ ___ __ _| |_(_) ___ _ __ | | \/ | ___ __| |_ _| | ___ _|_ _|_ __ / _| ___ _ __ _ __ ___ __ _| |_(_) ___ _ __ | ||
| |\/| |/ _ \ / _` | | | | |/ _ (_)| || '_ \| |_ / _ \| '__| '_ ` _ \ / _` | __| |/ _ \| '_ \ | | |\/| |/ _ \ / _` | | | | |/ _ (_)| || '_ \| |_ / _ \| '__| m'_ ` _ \ / _` | __| |/ _ \| '_ \ | ||
| | | | (_) | (_| | |_| | | __/_ | || | | | _| (_) | | | | | | | | (_| | |_| | (_) | | | | | | | | | (_) | (_| | |_| | | __/_ | || | | | _| (_) | | | | | | | | (_| | |_| | (_) | | | | | ||
|_| |_|\___/ \__,_|\__,_|_|\___(_)___|_| |_|_| \___/|_| |_| |_| |_|\__,_|\__|_|\___/|_| |_| | |_| |_|\___/ \__,_|\__,_|_|\___(_)___|_| |_|_| \___/|_| |_| |_| |_|\__,_|\__|_|\___/|_| |_| | ||
Line 21: | Line 21: | ||
local core = require('Module:Core') | local core = require('Module:Core') | ||
-- ================================================ | -- ==================================================================== | ||
local function langWrapper(text, textLang, userLang) | |||
local function langWrapper(text, textLang) | |||
-- code equivalent to https://commons.wikimedia.org/wiki/Template:Description | -- code equivalent to https://commons.wikimedia.org/wiki/Template:Description | ||
local | 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) | |||
local str = | |||
return | |||
end | end | ||
Line 58: | Line 34: | ||
-- ==================================================================== | -- ==================================================================== | ||
local function Build_html(args) | local function Build_html(args) | ||
local lang = args.lang -- | -- Permissions tag | ||
local dir = mw.language.new( lang ): | 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 = { | local params = { | ||
{field='description' , id='fileinfotpl_desc', | {field='description' , id='fileinfotpl_desc' , tag=description_tag, alt=true, wrapper='\n%s', td=' class="description"'}, | ||
{field='other_fields_1'}, | {field='other_fields_1'}, | ||
{field='date' , id='fileinfotpl_date', | {field='date' , id='fileinfotpl_date' , tag='wm-license-information-date', wrapper='\n%s', td=tag3}, | ||
{field='source' , id='fileinfotpl_src'}, | {field='source' , id='fileinfotpl_src' , tag='wm-license-information-source', alt=true, wrapper='\n%s'}, | ||
{field='author' , id='fileinfotpl_aut'}, | {field='author' , id='fileinfotpl_aut' , tag='wm-license-information-author', alt=true, wrapper='\n%s'}, | ||
{field='permission' , id='fileinfotpl_perm', | {field='permission' , id='fileinfotpl_perm' , tag=permission_tag, wrapper='\n%s'}, | ||
{field='other_versions' , id='fileinfotpl_ver', | {field='other_versions' , id='fileinfotpl_ver' , tag='wm-license-information-other-versions', wrapper='\n%s'}, | ||
{field='other_fields'} | {field='other_fields'} | ||
} | } | ||
local results = {} | local results = {} | ||
Line 79: | Line 60: | ||
local field, tag, cell1, cell2, id | local field, tag, cell1, cell2, id | ||
field = args[param.field] | 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 param.id then -- skip "other fields" parameter | ||
if | if field then -- add "id" to first <td> cell only if the field is present | ||
id = | id = string.format('id="%s" ', param.id) | ||
elseif | 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; '.. | ||
field = | '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 | end | ||
if field or | if field or args.demo then -- skip the row if still no field | ||
tag | tag = param.tag | ||
cell1 = | if string.sub(tag,1,10) == 'wm-license' then | ||
cell2 = | tag = mw.message.new( tag ):inLanguage(args.lang):plain() -- label message in args.lang language | ||
field = | 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 | ||
end | end | ||
Line 98: | Line 87: | ||
-- add table and outer layers | -- add table and outer layers | ||
local style = | local style = string.format('class="fileinfotpl-type-information toccolours vevent '.. | ||
'mw-content-%s" style="width: 100%%; direction: %s;" cellpadding="4"', dir, dir) | 'mw-content-%s" style="width: 100%%; direction: %s;" cellpadding="4"', dir, dir) | ||
results = | results = string.format('<table %s>\n\n%s\n</table>\n', style, table.concat(results)) | ||
results = | results = string.format('<div class="hproduct commons-file-information-table">\n%s\n</div>', results) | ||
return results | return results | ||
end | end | ||
Line 113: | Line 102: | ||
-- === Version of the function to be called from other LUA codes | -- === Version of the function to be called from other LUA codes | ||
-- =========================================================================== | -- =========================================================================== | ||
function p._information(args) | function p._information(args) | ||
Line 131: | Line 110: | ||
-- ============================================================================================ | -- ============================================================================================ | ||
local page = mw.title.getCurrentTitle() | local page = mw.title.getCurrentTitle() | ||
local namespace = page.namespace -- get page namespace | local namespace = page.namespace -- get page namespace | ||
if namespace==6 or namespace==10 then | if namespace==6 or namespace==10 then | ||
local allowedFields = {'description', 'date', 'permission', 'author', 'other_versions', | local allowedFields = {'description', 'date', 'permission', 'author', 'other_versions', | ||
'source','other_fields', 'other_fields_1', 'demo', 'lang', ' | 'source','other_fields', 'other_fields_1', 'demo', 'lang', 'mid', 'pageid'} | ||
local set, badField = {}, {} | local set, badField = {}, {} | ||
for _, field in ipairs(allowedFields) do set[field] = true end | for _, field in ipairs(allowedFields) do set[field] = true end | ||
Line 144: | Line 122: | ||
end | end | ||
if #badField>0 then | if #badField>0 then | ||
cats = | cats = string.format('\n;<span style="color:red">Error in [[Template:Information|{{Information}}'.. | ||
' template]]: unknown parameter "%s".</span>', table.concat(badField,'", "')) | ' template]]: unknown parameter "%s".</span>', table.concat(badField,'", "')) | ||
cats = cats .. '\n[[Category:Pages using Information template with incorrect parameter]]' | cats = cats .. '\n[[Category:Pages using Information template with incorrect parameter]]' | ||
end | end | ||
end | end | ||
if namespace==6 then -- files are required to have at least the 3 fields below | |||
if namespace==6 | |||
local reqFields = {description='Media lacking a description', author='Media lacking author information', source='Images without source'} | local reqFields = {description='Media lacking a description', author='Media lacking author information', source='Images without source'} | ||
for field, errCat in pairs(reqFields) do | for field, errCat in pairs(reqFields) do | ||
if not args[field] then | if not args[field] then | ||
cats = cats .. '\n[[Category:'.. errCat ..']]' | |||
cats = cats .. '\n[[Category:'.. errCat ..']]' | |||
end | end | ||
end | 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) | |||
-- | |||
if | |||
local | |||
if | |||
end | 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 | |||
local | |||
if | |||
end | |||
end | end | ||
end | end | ||
end | |||
-- ==================================================== | |||
-- === add tag templates used for tracking === | |||
-- ==================================================== | |||
local frame = mw.getCurrentFrame() | |||
if | -- 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' } | |||
end | if args.date then | ||
return | -- 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 | end | ||
-- | -- =========================================================================== | ||
-- | -- === Version of the function to be called from template namespace | ||
-- =========================================================================== | |||
function | 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 | |||
function p. | |||
-- | |||
end | end | ||
end | end | ||
for name, value in pairs( frame.args ) do | |||
if value ~= '' then -- nuke empty strings | |||
if | local name1 = string.gsub( string.lower(name), ' ', '_') | ||
args[name1] = value | |||
end | end | ||
end | end | ||
if | |||
if not (args.lang and mw.language.isSupportedLanguage(args.lang)) then | |||
args.lang = frame:callParserFunction( "int", "lang" ) -- get user's chosen language | |||
end | end | ||
-- call the inner "core" function | |||
-- | |||
function | |||
return p._information(args) | return p._information(args) | ||
end | end | ||
return p | return p | ||
Revision as of 00:07, 3 February 2023
Documentation for this module may be created at Module:Information/doc
--[[
__ __ _ _ ___ __ _ _
| \/ | ___ __| |_ _| | ___ _|_ _|_ __ / _| ___ _ __ _ __ ___ __ _| |_(_) ___ _ __
| |\/| |/ _ \ / _` | | | | |/ _ (_)| || '_ \| |_ / _ \| '__| m'_ ` _ \ / _` | __| |/ _ \| '_ \
| | | | (_) | (_| | |_| | | __/_ | || | | | _| (_) | | | | | | | | (_| | |_| | (_) | | | |
|_| |_|\___/ \__,_|\__,_|_|\___(_)___|_| |_|_| \___/|_| |_| |_| |_|\__,_|\__|_|\___/|_| |_|
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
]]
-- =======================================
-- === Dependencies ======================
-- =======================================
require('Module:No globals') -- used for debugging purposes as it detects cases of unintended global variables
local ISOdate = require('Module:ISOdate')._ISOdate -- date localization
local core = require('Module:Core')
-- ====================================================================
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