Code​Discussion​Edit​History​Links​Link count​Subpages:​Documentation​Tests​Results​Sandbox​Live codeAll modules
This module is rated as ready for general use. It has reached a mature form and is thought to be bug-free and ready for use wherever appropriate. To reduce server load and bad output, it should be improved by sandbox testing rather than repeated trial-and-error editing.
This module is subject to page protection. It is a highly visible module in use by a very large number of pages, or is substituted very frequently. Because vandalism or mistakes would affect many pages, and even trivial editing might cause substantial load on the servers, it is protected from editing.
Note: This module is used on a great lot of pages. In order not to put too much load on the servers, edits should be kept to a bare minimum. Please discuss proposed changes on the talk page first.
Afterwards, changes can initially be done at and tested with Module:Information/sandbox​.
  • Editing a module causes all pages that use the module to be re-rendered. If the module is used often, this can put a lot of load on the servers since it fills up the job queue.
  • Keep in mind that displays produced by modules used on file description pages also show up on other wikis.
Module providing back-end for {{Information}} template.
Test simple case:
{{#invoke:Information|information |description = description |date = 2021-12-05 |source = {{own}} |author = author |permission = permission |other versions = <gallery>File:Image-x-generic - black.svg</gallery> }}
Date5 December 2021
(Reusing this file)
Other versions
Test case with missing source, author and description:
{{#invoke:Information|information |description = |date = 2021-12-05 |source = |author = }}
This file has no description, and may be lacking other information.
Please provide a meaningful description of this file.
Date5 December 2021
This file is lacking source information.
Please edit this file's description and provide a source.
This file is lacking author information.
--[[ __ __ _ _ ___ __ _ _ | \/ | ___ __| |_ _| | ___ _|_ _|_ __ / _| ___ _ __ _ __ ___ __ _| |_(_) ___ _ __ | |\/| |/ _ \ / _` | | | | |/ _ (_)| || '_ \| |_ / _ \| '__| '_ ` _ \ / _` | __| |/ _ \| '_ \ | | | | (_) | (_| | |_| | | __/_ | || | | | _| (_) | | | | | | | | (_| | |_| | (_) | | | | |_| |_|\___/ \__,_|\__,_|_|\___(_)___|_| |_|_| \___/|_| |_| |_| |_|\__,_|\__|_|\___/|_| |_| 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 variableslocal ISOdate = require​(​'Module:ISOdate'​).​_ISOdate -- date localizationlocal core = require​(​'Module:Core'​)​
-- ==================================================​-- === Internal functions ===========================​-- ==================================================​
local function langWrapper(text, textLang) -- code equivalent to local language = textLang ) local dir = language:getDir() local LangName = language​:​ucfirst​(​mw​.​language​.​fetchLanguageName​( textLang, textLang)) local str = mw​.​ustring​.​format​(​'<span class="language %s"><b>%s:</b></span>'​, textLang, LangName) return mw​.​ustring​.​format​(​'<div class="description mw-content-%s" dir="%s" lang="%s">%s %s</div>', dir, dir, textLang, str, text​)​end​
-------------------------------------------------------------------------------​local function getBareLabel(id, userLang) -- code equivalent to require("Module:Wikidata label")._getLabel with Wikidata=- option local label, link -- build language fallback list local langList = mw​.​language​.​getFallbacksFor​(​userLang​) table.insert(langList, 1, userLang) for _, lang in ipairs(langList) do -- loop over language fallback list looking for label in the specific language label = mw​.​wikibase​.​getLabelByLang​(​id​, lang) if label then break end -- label found and we are done end return label or id​end​
-------------------------------------------------------------------------------​local function message(name, lang) return 'wm-license-information-'​..​name ):​inLanguage​(​lang​):​plain​()​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) local lang = args.lang -- user's language local dir = lang ):getDir() -- get text direction local desTag = mw​.​ustring​.​format​(​'<span class="summary fn" style="display:none">%s</span>'​, args.pagename) local prmTag = mw​.​ustring​.​format​(​"<br /><small>([[%s|%s]])</small>"​, message​(​'permission-reusing-link'​, lang), message​(​'permission-reusing-text'​, lang))
-- field specific preferences local params = { {field='description' , id='fileinfotpl_desc', tag2=desTag, td​=​'class="description"'​}, {​field​=​'other_fields_1'​}, {field='date' , id='fileinfotpl_date', td​=​mw​.​ustring​.​format​(​'lang="%s"'​, lang)}, {field='source' , id='fileinfotpl_src'}, {field='author' , id='fileinfotpl_aut'}, {field='permission' , id='fileinfotpl_perm', tag2=prmTag }, {field='other_versions' , id='fileinfotpl_ver', tag='other-versions'}, {field='other_fields'}, } local results = {} for _, param in ipairs(params) do local field, tag, cell1, cell2, id field = args[param.field] if then -- skip "other fields" parameter if type(field) == 'string' then -- add "id" to first <td> cell only if the field is present id = mw​.​ustring​.​format​(​'id="%s" ', elseif type(field) == 'table' then -- the field was initially not present, it contains only our -- warning text; flatten it so that mw.ustring.format() gets a string field = field.missing end if field or (args.demo and param.tag) then -- skip the row if still no field tag = message(param.tag or param.field, lang) .. (param.tag2 or '') cell1 = mw.ustring.format('<td %sclass="fileinfo-paramfield" lang="%s">%s</td>​\n​'​, id or '', lang, tag) cell2 = mw.ustring.format('<td %s>\n%s</td>', or '', field or '') field = mw.ustring.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 = mw​.​ustring​.​format​(​'class="fileinfotpl-type-information toccolours vevent '.. 'mw-content-%s" style="width: 100%%; direction: %s;" cellpadding="4"', dir, dir) results = mw​.​ustring​.​format​(​'<table %s>​\n\n​%s​\n​</table>​\n​'​, style, table.concat(results)) results = mw​.​ustring​.​format​(​'<div class="hproduct commons-file-information-table">​\n​%s​\n​</div>'​, results) return resultsend
-- ==================================================​-- === External functions ===========================​-- ==================================================​local p = {}
-- ===========================================================================​-- === Version of the function to be called from other LUA codes-- ===========================================================================​
-------------------------------------------------------------------------------​-- _information function creates a wikicode for {{Information}} template based on-- passed arguments (through "args") and data extracted from SDC. Allowed fields of -- "args" are : 'description', 'date', 'permission', 'author', 'other_versions', -- 'source','other_fields', 'other_fields_1', 'demo' and 'lang'​-------------------------------------------------------------------------------​-- Dependencies: p._SDC_Description, p._SDC_Source, p._SDC_Author, p._SDC_Date, -- Build_html, Module:ISOdate (_date)​-------------------------------------------------------------------------------​function p._information(args)
local cats = '' -- ============================================================================================ -- === add [[Category:Pages using Information template with incorrect parameter]] if needed === -- ============================================================================================ local page = mw​.​title​.​getCurrentTitle​() local lang = args.lang 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', 'strict'} 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 = mw​.​ustring​.​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 then -- apply ISODate to function to date string to convert date in ISO format to translated date string = ISOdate(, lang, '', 'dtstart', '100-999') end args.pagename = page.text
-- ==================================================== -- === harvest structured data === -- ==================================================== local entity = mw​.​wikibase​.​getEntity​() if namespace==6 and entity then -- file namespace -- call SDC functions only when needed local icon = true -- local field is missing -> get it from SDC args.description = args.description or p​.​_SDC_Description​(​entity​, lang, icon) args.source = args.source or p​.​_SDC_Source​(​entity​, lang, icon) = or p​.​_SDC_Author​(​entity​, lang, icon) = or p._SDC_Date(entity, lang, icon) end -- ==================================================== -- === add tracking templates and categories === -- ==================================================== -- add the template tag (all official infoboxes transclude {{Infobox template tag}} so files without that tag do not have an infobox mw​.​getCurrentFrame​():​expandTemplate​{ title = 'Infobox template tag' }
-- files are required to have at least the 3 fields below if args.strict~=false then local reqFields = {description='Media lacking a description', author='Media lacking author information', source='Images without source'} for field, errCat in pairs(reqFields) do if args[field] and mw​.​ustring​.​match​(​args​[​field​],​"^[%s%p]+$"​) then args[field]=nil; end -- ignore punctuation only fields if not args[field] then -- code equivalent to Template:Source missing, Template:Author missing, Template:Description missing local tag1 = 'class="boilerplate metadata" id="cleanup" style="text-align: center; background: #ffe; '.. 'margin: .75em 15%; padding: .5em; border: 1px solid #e3e3b0;' local tag2 = message​(​field​..​'-missing'​, lang) local tag3 = message​(​field​..​'-missing-request'​, lang) local dir = lang ):getDir() -- get text direction args[field] = {missing = mw​.​ustring​.​format​(​'<div %s direction: %s;" lang="%s">%s​\n​%s​\n​</div>'​, tag1, dir, lang, tag2, tag3)} cats = cats .. '\n[[Category:'.. errCat ..']]' end end end if namespace~=6 then cats = '' -- categories are added only to files end
return Build_html(args) .. cats​end​
-------------------------------------------------------------------------------​-- interface for other Lua codes to 5 functions for extracting description, source,-- author, date and location information from SDC. -- INPUTS:-- - "entity" - structure created by mw.wikibase.getEntity function-- - "lang" - users language​-------------------------------------------------------------------------------​-- Dependencies: langWrapper​-------------------------------------------------------------------------------​function p​.​_SDC_Description​(​entity​, lang, icon) -- create {{en|1=...}} template with SDC's caption local description, _ if entity and entity.labels then -- get label in users language or one of that language fallback list local label = core​.​langSwitch​(​entity​.​labels​, lang) local labels, D = {}, {} if label then -- show either matching language labels[lang] = label else -- or if missing then show all labels = entity.labels end for _, label in pairs(labels) do -- add {{en|1=....}} like wrapper if icon and #D==0 then -- add editAtSDC icon to the first description label.value = label.value .. core​.​editAtSDC​(​'ooui-php-4'​, lang) end table.insert(D, langWrapper​(​label​.​value​, label.language, lang)) end description = table.concat(D, '\n') end return description​end​
-------------------------------------------------------------------------------​-- Dependencies: Module:Wikidata_date "_date" function, Module:ISOdate "_ISOdate" function​-------------------------------------------------------------------------------​function p._SDC_Date(entity, lang, icon) -- get creation date from P571 (inception) -- Code can handle YYYY-MM-DD, YYYY-MM, and YYYY dates without any additional resources -- But can load [[Module:Wikidata date]] if needed local Date if entity and and then local snak = entity​.​claims​.​P571​[​1​].​mainsnak if (snak.snaktype == "value") then local v = snak.datavalue.value if v and (​v​.​calendarmodel​==​''​) and (​mw​.​ustring​.​sub​(​v​.​time​,​1​,​1​)​==​'+'​) then if v.precision >= 11 then -- day Date = mw​.​ustring​.​sub​(​v​.​time​,​2​,​11​) -- date in YYYY-MM-DD format elseif v.precision == 10 then -- month Date = mw​.​ustring​.​sub​(​v​.​time​,​2​,​8​) -- date in YYYY-MM format elseif v.precision == 9 then -- year Date = mw​.​ustring​.​sub​(​v​.​time​,​2​,​5​) -- date in YYYY format end if Date then -- translate Date = ISOdate(Date, lang, '', 'dtstart', '100-999') end end end if entity​.​claims​.​P571​[​1​].​qualifiers then -- non-trivial case: call heavy cavalery local getDate = require​(​"Module:Wikidata date")._date -- lazy loading: load only if needed local result = getDate(entity, 'P571', lang) -- display the date in user's language Date = result.str end end if icon and Date then Date = Date .. core​.​editAtSDC​(​'P571'​, lang) end return Date​end​
-------------------------------------------------------------------------------​-- Dependencies: none​-------------------------------------------------------------------------------​function p​.​_SDC_Source​(​entity​, lang, icon) -- get source from P7482 (source of file) -- Code can handle {{Own}} template and URLs local source, label if entity and and then local statement =[1] -- get URL is source is " file available on the internet (Q74228490) " if statement​.​mainsnak​.​datavalue​.​value​.​id​==​'Q74228490' and statement.qualifiers and statement​.​qualifiers​.​P973 then source = statement​.​qualifiers​.​P973​[​1​].​datavalue​.​value -- described at URL if statement​.​qualifiers​.​P137 then -- "operator" local id = statement​.​qualifiers​.​P137​[​1​].​datavalue​.​value​.​id label = getBareLabel(id, lang) source = '[' .. source ..' ' .. label ..']' end end -- add {{tl|own}} if source is "original creation by uploader (Q66458942)" if statement​.​mainsnak​.​datavalue​.​value​.​id​==​'Q66458942' then label = 'Wm-license-own-work'​):​inLanguage​(​lang​):​plain​() source = mw​.​ustring​.​format​(​'<span class="int-own-work" lang="%s">%s</span>'​,​lang​, label) end -- add {{tl|Own work by the original uploader}} if source is " Own work by the original uploader (Q87402110)" if statement​.​mainsnak​.​datavalue​.​value​.​id​==​'Q87402110' then label = getBareLabel​(​'Q87402110'​, lang) source = mw​.​ustring​.​format​(​'<span class="int-own-work" lang="%s">%s</span>'​,​lang​, label) end end if icon and source then source = source .. core​.​editAtSDC​(​'P7482'​, lang) end return source​end​
-------------------------------------------------------------------------------​-- Dependencies: Module:Core "getLabel" function​-------------------------------------------------------------------------------​function p​.​_SDC_Author​(​entity​, lang, icon) -- get author from P170 (creator) -- Code can handle usuall cases of "[[User:Example|Example]]" as well as users with Wikidata Item IDs local author if entity and and then local creators = {} for _,statement in ipairs​(​entity​.​claims​.​P170​) do if statement​.​mainsnak​.​snaktype == "value" then -- Creator has item ID local val = statement​.​mainsnak​.​datavalue​.​value​.​id table.insert(creators, core.getLabel(val, lang)) elseif statement​.​mainsnak​.​snaktype == "somevalue" then -- Creator defined by username if statement.qualifiers then -- author name string (P2093) local qual = {} local properties = {P2093='authorStr', P4174='username', P3831='role', P2699='url'} for prop, field in pairs( properties ) do if statement​.​qualifiers​[​prop​] then qual[field] = statement​.​qualifiers​[​prop​][​1​].​datavalue​.​value end end local role = '' if qual.role and[2] then -- add role only is multiple creators role = '&nbsp;(' .. core​.​getLabel​(​qual​.​role​.​id​, lang) .. ')' end if qual.username and qual.authorStr then -- author name string (P2093) & Wikimedia username (P4174) table.insert(creators, '[[User:'​..​qual​.​username​..​'|'​..​qual​.​authorStr​..​']]'​..​role​) elseif qual.username and not qual.authorStr then -- no author name string (P2093) & Wikimedia username (P4174) table.insert(creators, '[[User:'​..​qual​.​username​..​'|'​..​qual​.​username​..​']]'​..​role​) elseif qual.url and qual.authorStr then -- author name string (P2093) & URL (P2699) table.insert(creators, '['..qual.url..' '​..​qual​.​authorStr​..​']'​..​role​) elseif qual.url and not qual.authorStr then -- no author name string (P2093) & URL (P2699) table.insert(creators, qual.url..role) elseif qual.authorStr then -- author name string (P2093) table.insert(creators, qual.authorStr..role) end end end end -- end for author = table.concat(creators, ', ') end if icon and author then author = author .. core​.​editAtSDC​(​'P170'​, lang) end return author​end​
-------------------------------------------------------------------------------​-- Dependencies: Module:Code "getLabel" function​-------------------------------------------------------------------------------​function p​.​_SDC_Location​(​entity​, lang, icon) -- get location P276 (location) local location, prop if entity and and then local snak = entity​.​claims​.​P1071​[​1​].​mainsnak if (snak.snaktype == "value") then location = core​.​getLabel​(​snak​.​datavalue​.​value​.​id​, lang) prop = 'P1071' end end if entity and and then local snak = entity​.​claims​.​P276​[​1​].​mainsnak if (snak.snaktype == "value") then location = core​.​getLabel​(​snak​.​datavalue​.​value​.​id​, lang) prop = 'P276' end end if icon and location then location = location .. core.editAtSDC(prop, lang) end return locationend
-- ===========================================================================​-- === Version of the functions to be called from template namespace-- ===========================================================================​
-------------------------------------------------------------------------------​-- information function creates a wikicode for {{Information}} template based on-- passed arguments (through "frame") and data extracted from SDC. Allowed template-- arguments are : 'description', 'date', 'permission', 'author', 'other_versions', -- 'source','other_fields', 'other_fields_1', 'demo' and 'lang'. All inputs do not -- depend on capitalization and all "_" can be replaced with spaces.​-------------------------------------------------------------------------------​-- Dependencies: p._information​-------------------------------------------------------------------------------​function p.information(frame) local args = core.getArgs(frame) args.strict = true return p._information(args) end​
-------------------------------------------------------------------------------​-- interface for templates to 5 functions for extracting description, source,-- author, date and location information from SDC. -- INPUTS (templaate parameters):-- * "mid" - pageID defining a file. Optional, defaulting to the current file.-- * "lang" - users language. Optional defaulting to the language of the user-- * "icon" - add "Edit this at Wikidata" icon? boolean ( 'true'/'false', 'yes'/'no', 1/0​-------------------------------------------------------------------------------​-- Dependencies: getEntity​-------------------------------------------------------------------------------​local function parseFrame(frame) local args = core.getArgs(frame) local entity = mw​.​wikibase​.​getEntity​( args.mid ) local icon = core.yesno(args.icon, true) return {entity, args.lang, icon}end
function p​.​SDC_Description​(​frame​) return p​.​_SDC_Description​(​unpack​(​parseFrame​(​frame​)))​end​
function p​.​SDC_Source​(​frame​) return p​.​_SDC_Source​(​unpack​(​parseFrame​(​frame​)))​end​
function p.SDC_Author(frame) return p​.​_SDC_Author​(​unpack​(​parseFrame​(​frame​)))​end​
function p.SDC_Date(frame) return p​.​_SDC_Date​(​unpack​(​parseFrame​(​frame​)))​end​
function p​.​SDC_Location​(​frame​) return p​.​_SDC_Location​(​unpack​(​parseFrame​(​frame​)))​end​
return p​
-------------------------------------------------------------------------------​-- List of exported functions​-------------------------------------------------------------------------------​-- information-- SDC_Description-- SDC_Source-- SDC_Author-- SDC_Date-- SDC_Location
Last edited on 23 January 2021, at 03:51
Wikimedia Commons
Files are available under licenses specified on their description page. All structured data from the file namespace is available under the Creative Commons CC0 License; all unstructured text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Terms of Use and the Privacy Policy.
Privacy policy
Terms of Use
HomeRandom Nearby Log in Settings DonateAbout Wikimedia CommonsDisclaimers