Module:Information
Appearance
From Wikimedia Commons, the free media repository
Lua
Code Discussion Edit History Links Link count Subpages: Documentation Tests Results Sandbox Live code All 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.
[画像:Protected] 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.
Examples
Code | Render |
---|---|
Test simple case:
{{#invoke:Information|information |description = description |date = 2025年04月09日 |source = {{own}} |author = author |permission = permission |other versions = <gallery>File:Image-x-generic - black.svg</gallery> }} |
DescriptionInformation
description
Date
Source
own
Author
author
Permission
(Reusing this file) permission |
Test case with missing source, author and description:
{{#invoke:Information|information |description = |date = 2025年04月09日 |source = |author = }} |
DescriptionInformation
This file has no description, and may be lacking other information.
Please provide a meaningful description of this file. Date
Source
This file is lacking source information.
Please edit this file's description and provide a source. Author
This file is lacking author information.
|
Code
--[[ __ __ _ _ ___ __ _ _ | \/ | ___ __| |_ _| | ___ _|_ _|_ __ / _| ___ _ __ _ __ ___ __ _| |_(_) ___ _ __ | |\/| |/ _ \ / _` | | | | |/ _ (_)| || '_ \| |_ / _ \| '__| '_ ` _ \ / _` | __| |/ _ \| '_ \ | | | | (_) | (_| | |_| | | __/_ | || | | | _| (_) | | | | | | | | (_| | |_| | (_) | | | | |_| |_|\___/ \__,_|\__,_|_|\___(_)___|_| |_|_| \___/|_| |_| |_| |_|\__,_|\__|_|\___/|_| |_| 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('strict') -- 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') -- ================================================== -- === Internal functions =========================== -- ================================================== local function langWrapper(text, textLang) -- code equivalent to https://commons.wikimedia.org/wiki/Template:Description local language = mw.language.new( 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" dir="%s" lang="%s">%s %s</div>', 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 mw.message.new( '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 = mw.language.new( 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='other_fields_0'}, {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 param.id 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" ', param.id) 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>', param.td or '', field or '') field = mw.ustring.format('<tr>\n%s%s\n</tr>\n\n', cell1, cell2) end end table.insert(results, field) end -- To save space in the templatelinks table, skip templatestyles in the File namespace on Commons; -- files get a copy of these styles via [[MediaWiki:Filepage.css]] instead. -- See [[Module talk:Information/styles.css]]. local templatestyles = '' if args.namespace ~= 6 or not(mw.site.server:match('//commons.wikimedia.org$')) then templatestyles = mw.getCurrentFrame():extensionTag{ name = 'templatestyles', args = { src = 'Module:Information/styles.css' } } end -- add table and outer layers local style = mw.ustring.format('class="fileinfotpl-type-information vevent" dir="%s"', 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%s\n</div>', templatestyles, results) return results end -- ================================================== -- === 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_0', '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_0', 'other_fields_1', 'demo', 'lang', 'strict','sdc'} 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:var(--color-error,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 args.date then -- apply ISODate to function to date string to convert date in ISO format to translated date string args.date = ISOdate(args.date, lang, '', 'dtstart', '100-999') end args.pagename = page.text args.namespace = namespace -- ==================================================== -- === harvest structured data === -- ==================================================== local entity = mw.wikibase.getEntity() if namespace==6 then entity = mw.wikibase.getEntity() elseif args.sdc then entity = mw.wikibase.getEntity(args.sdc) end if (namespace==6 or args.sdc) 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) args.author = args.author or p._SDC_Author(entity, lang, icon) args.date = args.date 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; color: inherit;background: var(--background-color-warning-subtle,#ffe); '.. 'margin: .75em 15%; padding: .5em; border: 1px solid var(--border-color-content-removed,#e3e3b0);' local tag2 = message(field..'-missing', lang) local tag3 = message(field..'-missing-request', lang) local dir = mw.language.new( 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 entity.claims and entity.claims.P571 then local snak = entity.claims.P571[1].mainsnak if (snak.snaktype == "value") then local v = snak.datavalue.value if v and (v.calendarmodel=='http://www.wikidata.org/entity/Q1985727') 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 entity.claims and entity.claims.P7482 then for _,statement in ipairs(entity.claims.P7482) do if statement.mainsnak.datavalue then -- 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 = mw.message.new( '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 if source then break end end 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 entity.claims and entity.claims.P170 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 entity.claims.P170[2] then -- add role only is multiple creators role = ' (' .. 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 entity.claims and entity.claims.P1071 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 entity.claims and entity.claims.P276 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 location end -- =========================================================================== -- === 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_0', 'other_fields_1', 'demo', 'sdc' 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