Modul:Databox
For dokumentation se Skabelon:Databox och mere detaljeret dokumentation på svensk.
Brug
redigér{{#invoke:Databox|databox}}
-- This extended version of Databox is stored at https://sv.wikipedia.org/wiki/Modul:Databox, but can be used by other languages
-- Versions: (Besides minor adjustments to the property_blacklist and layout)
-- 2024-03-03 Parameter "keep_title_case" to not change first letter to upper case (default false)
-- 2023-06-18 Shows monolingualtext but only in local language - and maximum one value per property
-- Can show any commonsMedia file that has media caption qualifier in the local language, or with content in ("language of work" qualifier) the local language
-- Can show several maps if several coordinates, limited by parameter maxFiles (default 1).
-- 2023-06-11 Locator map image shown if it has media caption in the local language
-- 2020-05-25 Hide "is instance of" -> "human"
-- 2020-05-25 Category:Databox that shows qid code
-- 2020-05-24 Years linked to articles. Decades, centuries and millennia formated in local language.
-- 2020-05-13 P155 (follows) and P156 (followed by) merged into one "Chronology" list, also showing current object.
-- Parameter "list_separator" for replacing comma in lists.
-- 2020-05-10 Parameter "era" for choosing if year "BCE" (or similar in local language) should be replaced by "BC", empty string or other.
-- Upper-case initial letter of P31 (instance of).
-- 2020-05-05 P31 hidden if too long list. Administrative wiki category if too long list.
-- 2020-05-02 More than two parent/child levels in bulleted list.
-- 2020-05-01 Property short names based on P1813. Image legend/caption.
-- 2020-04-28 Properties linked to articles (based on Property:P1629 of the property).
-- Datatype "url" not shown (except for official web site). Input parameter "levels".
-- 2020-04-27 Two higher and two lower levels of child and parent items shown as bulleted list for some properties
-- 2020-04-21 Parameters "width", "height", "zoom" and "list_length". Soft hyphens auto-inserted in long property names.
-- 2020-04-18 (Monolingual text strings hidden.) Property name hidden if no good value. First image shown if several images.
-- 2020-04-16 Description shown (only in local language). First letter of label upper-case.
-- 2020-04-13 Values of datatype "quantity" shown. Pen hidden in printout.
-- 2020-04-13 Mapframe code copied from the 2019-03-04 af.wikipedia.org version.
-- 2020-04-07 Imported from the 2019-04-26 fr.wikipedia.org version
-- Blocked properties:
local property_blacklist = {
'P360', --is a list of
'P4224', --category contains
'P935', -- Commons gallery
'P1472', -- Commons Creator page
'P1612', -- Commons Institution page
'P373', -- Commons category
'P3722', -- Commons maps category
'P7561', -- for the interior of the item
'P1151', -- topic's main Wikimedia portal
'P1424', -- topic's main template
'P910', -- topic's main category
'P1200', -- bodies of water basin category
'P1792', -- category of associated people
'P1464', -- category for people born here
'P1465', -- category for people who died here
'P1791', -- category of people buried here
'P1740', -- category for films shot at this location
'P2033', -- Category for pictures taken with camera
'P2517', -- category for recipients of this award
'P4195', -- category for employees of the organization
'P1754', -- category related to list
'P301', -- category's main topic
'P971', -- category combines topics
'P3876', -- category for alumni of educational institution
'P1753', -- list related to category
'P7867', -- category for maps
'P1921', -- Wikidata RDF URI format
'P3921', -- Wikidata SPARQL query equivalent
'P1204', -- Wikimedia portal's main topic
'P1423', -- template's main topic
'P1709', -- equivalent class
'P3950', -- narrower external class
'P2888', -- exact match
'P1382', -- coincident with
'P2670', -- has parts of the class
'P3113', -- does not have part
'P2737', -- union of
'P2738', -- disjoint union of
'P2445', -- metasubclass of
'P1963', -- properties for this type
'P3176', -- uses property
'P1889', -- different from
'P460', -- said to be the same as
'P2959', -- permanent duplicated item
'P2860', -- cites
'P5125', -- wikimedia outline
'P5008', -- on focus list of Wikimedia project
'P7084', -- related category
'P1687', -- Wikidata main property for this item
'P2559', -- Wikidata usage instructions
'P5692', -- Wikidata dummy value
'P1343', -- described by source
'P972', -- catalogue
'P1282', -- OSM tag or key
'P553', -- web site account
'P968', -- email
'P2572', -- hashtag
'P3761', -- IPv4 range
'P4839', -- Wolfram Language entity code
'P6104', -- Maintained by Wikiproject
'P5996', -- Category for films in this language
'P2354', -- list article (seldom available in local language)
'P6365', -- member category
'P528', -- catalog code
'P667', -- ICPC 2 ID
'P944', -- Code of nomenclature
'P1438', -- Jewish Encyclopedia ID (Russian)e
'P1402', -- Foundational Model of Anatomy ID
'P1461', -- Patientplus ID
'P1692', -- ICD-9-CM code
'P1748', -- NCI Thesaurus ID
'P1193', -- prevalence (often different value in different countries)
'P2176', -- drug used for treatment (we avoid medical advise)
'P2293', -- genetic association
'P1814', -- Japanese name in kana
'P747', -- editions
'P1433', -- published in
'P4969', -- derivative work
'P217', -- inventory number
'P2540', -- Aarne–Thompson–Uther Tale Type Index
'P1036', -- DDC
'P1149', -- LCC
'P1150', -- RVK
'P1190', -- UDC
'P1987', -- MCN code
'P2263', -- ISOCat id
'P2283', -- Uses
'P2184', -- History of subject. (Should be shown if article in local language)
'P989', -- spoken text. (Should be shown if in local language)
'P1793', -- format as a regex
'P4354', -- search formatter URL
'P5869', -- model item
'P859', -- sponsor
'P7973', -- quantity symbol (LaTeX)
'P6216', -- copyright status
'P1830', -- owner of (seldom useful)
'P487', -- Unicode character
'P8933', -- category for the view from the item
'P1299', -- depicted by
'P6112', -- category for members of a team
'P8687', -- social media followers
'P1559', -- name in native language
'P8596', -- category for multimedia files depicting exterior views of this item
'P7763', -- copyright status as a creator
'P8989', -- category for the view of the item
'P7782', -- category for ship name
'P2817', -- appears in the heritage monument list
'P8402' -- open data portal
}
-- Exceptions to the datatype blocking:
local property_whitelist = {
'P856', -- official website
'P3896',-- geoshape
'P345', -- IMDB id
'P6375' -- street address
}
-- Properties with higher level items:
local properties_with_parents = {
'P131', -- located in the administrative territorial entity
'P144', -- based on
'P155', -- follows
'P171', -- parent taxon
'P276', -- location
'P279', -- subclass of
'P361', -- part of
'P706', -- located on terrain feature
'P749', -- parent organization
'P807', -- separated/forked from
'P1365', -- replaced
'P1647', -- subproperty of
'P3730' -- next higher rank
}
local properties_with_children = {
-- Properties with lower level items:
'P150', -- contains administrative territorial entity
'P156', -- followed by
'P355', -- subsidiary
'P527', -- has part
'P1012', -- contains
'P1366', -- replaced by
'P3729', -- next lower rank
'P4330', -- contains
'P7888' -- merged into
}
local function buildInteractiveMap(width, point, item_id, zoom)
--Utility function to build maps
local geojson = {
{
type = 'Feature',
geometry = {
type = "Point",
coordinates = {point.longitude, point.latitude}
},
properties = {
title = point.text or '',
['marker-symbol'] = point.marker or 'marker',
['marker-color'] = point.markercolor or "#224422",
}
}
}
local args = {
['height'] = width,
['width'] = width,
['frameless'] = 'frameless',
['align'] = 'center',
['latitude'] = point.latitude,
['longitude'] = point.longitude,
['zoom'] = zoom,
['lang'] = lang -- fallbacks to wiki language if local name is missing. )
}
return mw.getCurrentFrame():extensionTag('mapframe', mw.text.jsonEncode(geojson), args)
end
function Set(list) -- values to booleans with keys
local set = {}
for _, l in pairs(list) do
set[l] = true
end
return set
end
function listCase(str)
-- Capitalizes first visible character of list produced by formatStatements()
-- Example: <span><span>[[link|first item]]</span>, <span>second item</span></span>
-- --> <span><span>[[link|First item]]</span>, <span>second item</span></span>
return str
:gsub('^<span><span>%[%[(.-)|(.-)%]%]</span>',
function(a,b)
return '<span><span>[[' .. a .. '|'
.. b:gsub('^%l', string.upper)
.. ']]</span>'
end)
:gsub('^<span><span>(%l)',
function(a)
return '<span><span>' ..string.upper(a)
end)
end
function listSeparate(str, list_separator)
-- Replaces comma in list produced by formatStatements()
-- Example: list_separator = ';<br>'
-- str = <span><span>[[link|first item]]</span>, <span>second item</span></span>
-- -> <span><span>[[link|first item]]</span>;<br> <span>second item</span></span>
if list_separator ~= ',' then
return str
:gsub('</span>,', '</span>'..list_separator)
else
return str
end
end
function hyphenate(str, lang)
-- Inserts soft hyphens in long words, typically before each consonant that is followed by a vowel (lower-case letters)
-- Should work good enough for most languages. Language specific exceptions may be added.
local nonHyphenatedLanguages = Set{'ar', 'he', 'zh', 'ja', 'ko', 'vi', 'fa', 'ps'}
if nonHyphenatedLanguages[lang] then -- Not languages without alphabetic writing system or with few vowels
return str
end
result = ''
for word in str:gmatch("%S+") do
if #word < 10 then
result = result .. ' ' .. word
else
result = result .. ' '
.. word:sub(1,3) -- Not too early in word
.. word:sub(4)
:gsub("([bcdfghjklmnpqrstvwxzđçčĉñŋĝĥĵŝšŧžßÐðþğşśćńŁżźбвгжийклмнпрст]"
.. "[aouåeiyäöæøáéíóúýàèâêëüãŭœāēīōūəąęóадеёзоу])",
"­%1") -- Insert soft-hyphens before each consonant that is followed by vowel
:gsub("­([\128-\193])", "%1" ) -- Revert split of two-byte UTF-8 character
:gsub("-(%a?%a?%a?%a?)­", "-%1"):gsub("­(%a?%a?%a?%a?)-", "%1-") -- Not too near a hard hyphen
-- Some Scandinavian exceptions for wikidata properties, relevant to similar languages:
:gsub("­x", "x­") -- Example: tids-komp-le-xi-tet -> tids-komp-lex-i-tet
:gsub("sc­h", "­sch") -- Example: sc-h -> -sch
:gsub("ss­j", "s­sj")-- Example: ss-j-> s-sj
:gsub("n­g", "ng­") -- Example: n-g -> ng-
:gsub("ngs", "ngs­") -- Example: Befolk-ningsg-rup-pe -> Befolk-nings-g-rup-pe, Rege-ring-s-che-fens -> Rege-rings-chefens
:gsub("g­rup­pe", "­gruppe") -- Example: g-rup-pe -> -gruppe
:gsub("nist­ra", "nis­tra") -- Example: admi-nist-ra-tion -> admi-nis-tra-tion
:gsub("­ror­ga[­]*n", "r­organ") -- Example: dotte-ror-ga-ni-sa-tion -> dotter-organi-sa-tion
:gsub("­rob[­]*jek", "r­objek") -- Example: dot-te-rob-jekt -> dot-ter-objekt
:gsub("s­ta­tus", "­status") -- Example: skydds-status
:gsub("k­las[­]*s", "­klass") -- Example: deci-malk-las-si-fi-ka-tion -> deci-mal-klas-si-fi-ka-tion
:gsub("­nom­rå­de", "n­område") -- Example: vatte-nom-rå-de -> vatten-område
:gsub("­som­rå­de", "s­område") -- Example: Rets-gyl-dig-hed-som-rå-de -> Rets-gyl-dig-heds-om-rå-de
:gsub("ra­lort", "ral­ort") -- Example: central-ort
:gsub("s­kydd", "­skydd") -- Example: Kul-turs-kydd -> Kul-tur-skydd
:gsub("k­ri­te­ri", "­kri­te­ri")-- Example: Värld-sarvsk-ri-te-rium -> Värld-sarvs-kri-te-rium
:gsub("guasp­he", "gua­sphe") -- Example: lingua-sphere
:gsub("gars­kap", "gar­skap") -- Example: medbor-gars-kap -> medbor-gar-skap
:gsub("k­var­ter", "­kvarter") -- Example: Hovedk-var-ter -> Hoved-kvarter
:gsub("s­ted", "­sted") -- Example: Pro-duk-tionss-ted -> Pro-duk-tions-sted
:gsub("­­", "­") -- Example -- -> -
end
end
return result:sub(2,-1)
-- :gsub("­", "-") -- Show soft hyphens as hard hyphens. Only for sandboxed test purposes.
end
function year(str, lang, replaceTime)
-- Postprocesses years (datatype time) in local language
-- Incorrect formating of the first decade.
if lang == 'sv' then
str = str
:gsub("<span>0</span>", "<span>00-talet</span>")
:gsub("<span>0 BCE</span>", "<span>00-talet f.v.t.</span>")
end
-- Replace BCE with BC (or corresponding in local language) depending on era template parameter:
if replaceTime then
for p,r in pairs(replaceTime) do
str = str:gsub(p, r)
end
end
-- Link years to articles:
str = str
:gsub("([%s>])(%d?%d?%d?%d)</span>", "%1[[%2]]</span>") -- April 1852 -> April [[1852]]
:gsub("([%s>])(%d?%d?%d?%d) ([%a%.]*)</span>", "%1[[%2 %3]]</span>") -- April 20 BCE -> April [[20 BCE]]
-- Format decades, centuries and millennias correctly in local language, and link to articles:
if lang=='sv' then
str = str
:gsub("(%d?1%d)%.? år([h|t])(%a+)det?", "%1:e år%2%3det") -- 12. årtusende -> 12:e årtusendet
:gsub("(%d?%d?[1-2])%.? år([h|t])(%a+)det?", "%1:a år%2%3det") -- 2. århundrade -> 2:a århundradet
:gsub("(%d?%d?[0,3-9])%.? år([h|t])(%a+)det?", "%1:e år%2%3det") -- 13 århundrandet f.Kr. -> 13:e århundradet f.Kr
:gsub("<span>(%d?%d?%d?)00-talet</span>", "<span>[[%100-talet (decennium)]]</span>") -- 1900-talet -> [[1900-talet (årtionde)]]
:gsub("<span>(%d?%d?%d?)00-talet ([%a%.]*)</span>", "<span>[[%100-talet (decennium) %2]]</span>") -- 100-talet f.Kr. -> [[100-talet f.Kr. (decennium)]]
:gsub("(%d?%d?%d):[a|e] århundradet",
function(a)
return tonumber(a)-1 .. '00-talet'
end) -- 21:a århundradet -> 2000-talet
:gsub("<span>(%d+)-talet</span>", "<span>[[%1-talet]]</span>") -- 2000-talet -> [[2000-talet]]
:gsub("<span>(%d+)-talet ([%a%.]*)</span>", "<span>[[%1-talet %2]]</span>") -- 000-talet f.Kr. -> [[000-talet f.Kr.]]
:gsub("(%d?%d?%d):[a|e] årtusendet",
function(a)
return tonumber(a)-1 .. '000-talet'
end) -- 2:a århundradet -> 2000-talet
:gsub("<span>(%d+)-talet</span>", "<span>[[%1-talet (millennium)]]</span>") -- 2000-talet -> [[2000-talet (millennium)]]
:gsub("<span>(%d+)-talet ([%a%.]*)</span>", "<span>[[%1-talet %2 (millennium)]]</span>") -- 0000-talet f.Kr. -> [[0000-talet f.Kr. (millennium)]]
end
return str
end
local p = {}
function p.databox(frame)
local args = frame:getParent().args
local itemId = nil
if args.item then
itemId = args.item
end
local item = mw.wikibase.getEntity(itemId)
if item == nil then
mw.addWarning("Wikidata item not found")
return ""
end
local width = '260' -- default max width of template, image and map, and height of map
if args.width then
width = args.width
end
local height = '240' -- default max height of image. hidden if <= 0.
if args.height then
height = args.height
end
local zoom = 12 -- default map zoom level. hidden if <0.
if args.zoom then
zoom = tonumber(args.zoom)
end
local list_length = 8 -- default max no of values in lists
if args.list_length then
list_length = tonumber(args.list_length)
end
local list_separator = ',' -- default no replacement of comma in lists
if args.list_separator then
list_separator = args.list_separator
end
local levels = 3 -- default max no of child and parent levels
if args.levels then
levels = tonumber(args.levels)
end
local maxFiles = 1 -- default max no of coordinate location maps
if args.maxFiles then
maxFiles = tonumber(args.maxFiles)
end
local langObject = mw.language.getContentLanguage()
local lang = langObject:getCode()
local langIdDict = { -- Dictionary for translating language code to language Wikidata item id
['af'] = 'Q14196',
['atj'] = 'Q56590',
['be-tarask'] = 'Q8937989',
['ca'] = 'Q7026',
['ceb'] = 'Q33239',
['ckb'] = 'Q36811',
['cs'] = 'Q9056',
['da'] = 'Q9035',
['dag'] = 'Q32238',
['de'] = 'Q188',
['en'] = 'Q1860',
['es'] = 'Q1321',
['ewe'] = 'Q30005',
['fi'] = 'Q1412',
['fa'] = 'Q9168',
['fr'] = 'Q150',
['frr'] = 'Q28224',
['haw'] = 'Q33569',
['he'] = 'Q9288',
['hi'] = 'Q1568',
['it'] = 'Q652',
['ja'] = 'Q5287',
['kab'] = 'Q35853',
['ko'] = 'Q9176',
['mzn'] = 'Q13356',
['nap'] = 'Q33845',
['nds'] = 'Q25433',
['nl'] = 'Q10000',
['no'] = 'Q9043',
['nqo'] = 'Q18546266',
['pap'] = 'Q33856',
['pl'] = 'Q809',
['pcm'] = 'Q33655',
['pt'] = 'Q5146',
['ru'] = 'Q7737',
['rue'] = 'Q26245',
['sh'] = 'Q9301',
['sv'] = 'Q9027',
['tr'] = 'Q256',
['uk'] = 'Q8798',
['vi'] = 'Q9199',
['zh'] = 'Q7850'
}
local dump = ''
local langId -- Local language Wikidata item id
langId = langIdDict[lang] or nil
local edit_message = mw.message.new('vector-view-edit'):plain() .. ' Wikidata'
-- Date formating
local bceDict = { -- Dictionary: Before current era (BCE) in different languages
['da'] = 'f.v.t.',
['en'] = 'BCE',
['sv'] = 'f.v.t.'
}
local bcDict = { -- Dictionary: Before Christ (BC) in different languages
['da'] = 'f.Kr.',
['en'] = 'BC',
['sv'] = 'f.Kr.'
}
local bc = bcDict[lang] or 'BC'
local bce = bceDict[lang] or 'BCE'
local era = bc -- default era
if args.era then
if args.era == 'BC' then
era = bc -- replace 'BCE' by 'BC' in content language
elseif args.era == 'BCE' then
era = bce -- replace 'BC' by 'BCE' in content language
else
era = args.era -- replace 'BCE' and 'BC' by arbitrary argument value, for example empty string
end
end
local replaceTime = {} -- global variable
replaceTime[' BCE'] = ' '..era
replaceTime[' '..bce] = ' '..era
replaceTime[' '..bc] = ' '..era
local noValueDict = { -- Dictionary: No value
['da'] = 'ingen værdi',
['en'] = 'no value',
['sv'] = 'inget värde'
}
local wikicategory = ''
local databoxRoot = mw.html.create('div')
:addClass('infobox')
:css({
float = 'right',
clear = 'right',
border = '1px solid #aaa',
['background-color'] = '#f9f9f9',
['width'] = width .. 'px',
padding = '0 0.4em',
margin = '0 0 0.4em 0.4em',
})
--Title
local title = item:getLabel() or mw.title.getCurrentTitle().text
if args.keep_title_case == nil or #args.keep_title_case == 0 or args.keep_title_case == 'false' then
title = langObject:ucfirst(title)
end
databoxRoot:tag('div')
:css({
['text-align'] = 'center',
['background-color'] = 'LightGrey',
padding = '0em 0.4',
margin = '0em 0',
['font-size'] = '120%',
['font-weight'] = 'bold',
})
:wikitext(title)
--Description
local descr, descrLang = item:getDescriptionWithLang()
if descrLang == lang then -- Do not show any fallback language
databoxRoot:tag('div')
:css({
['text-align'] = 'center',
['vertical-align'] = 'text-top',
['font-size'] = '90%',
['line-height'] = '140%',
padding = '0.2em 0.4',
margin = '0.0em 0.4',
['padding-bottom'] = '0.5em',
})
:wikitext(langObject:ucfirst(descr):sub(1,-1))
:wikitext('<sup class="noprint Inline-Template"> [[File:Arbcom_ru_editing.svg|'
.. edit_message .. '|8px|baseline|class=noviewer|link=https://www.wikidata.org/wiki/'
.. item.id .. ']]</sup>')
end
--Show first good image with legend/caption in content language, or first good image
if tonumber(height) > 0 then
local images = item:getBestStatements('P18') -- p18 is 'image'
if #images >= 1 then
local image = images[1]
for _, i in pairs(images) do
if i.qualifiers and i.qualifiers.P2096 then -- P2096 is 'caption'
for _, c in pairs(i.qualifiers.P2096) do
if c.snaktype == 'value' and c.datavalue.value.language == lang then
caption = c
image = i
break
end
end
end
if caption then
break
end
end
if image.mainsnak.snaktype == 'value' then
databoxRoot
:tag('div')
:css({
['text-align'] = 'center',
padding = '0.0em 0.4',
})
:wikitext('[[File:' .. image.mainsnak.datavalue.value .. '|frameless|'
.. width .. 'x' .. height .. 'px]]')
if caption then
databoxRoot
:tag('div')
:css({
['text-align'] = 'center',
['font-size'] = '90%',
['line-height'] = '140%',
['padding-bottom'] = '0.5em',
})
:wikitext(caption.datavalue.value.text)
:wikitext('<sup class="noprint Inline-Template"> [[File:Arbcom_ru_editing.svg|'
.. edit_message .. '|8px|baseline|class=noviewer|link=https://www.wikidata.org/wiki/'
.. item.id .. '#' .. 'P18' .. ']]</sup>')
end
end
end
end
--Table:
local dataTable = databoxRoot
:tag('table')
:css({
['text-align'] = 'left',
['font-size'] = '90%',
['line-height'] = '140%',
['hyphens'] = 'auto', -- works only in some browsers and languages
['word-break'] = 'break-word',
['width'] = '100%',
['table-layout'] = 'fixed',
['padding-bottom'] = '0.5em',
})
--Instance of:
local dataValues
local statements = item:getBestStatements('P31')
if #statements > list_length then -- Hide too long list of values
if lang == 'sv' then
wikicategory = wikicategory .. '[[Kategori:Databox med dold lång lista]]'
end
elseif #statements >= 1 then
dataValues=item:formatStatements('P31').value
if lang == 'sv' then
if dataValues:match("<span>%[%[Människa|människa%]%]</span>") then -- Remove 'is instance of' -> 'human' TODO: Same for other languages
if #statements == 1 then
dataValues = ''
else
dataValues = dataValues:gsub("<span>%[%[Människa|människa%]%]</span>,?%s?", "")
end
end
elseif lang == 'da' then
if dataValues:match("<span>%[%[Menneske|menneske%]%]</span>") then -- Remove 'is instance of' -> 'human'
if #statements == 1 then
dataValues = ''
else
dataValues = dataValues:gsub("<span>%[%[Menneske|menneske%]%]</span>,?%s?", "")
end
end
end
dataValues = dataValues:gsub(", </span>$", "</span>") -- Removing ending comma after removed ", human"
if #dataValues > 0 then
dataValues=listCase(dataValues)
dataTable:tag('caption')
:css({
['background-color'] = 'LightGrey',
['font-weight'] = 'bold',
['margin-top'] = '0.4em',
margin = '0.5em 0',
padding = '1em 1',
})
:wikitext(dataValues)
:wikitext('<sup class="noprint Inline-Template"> [[File:Arbcom_ru_editing.svg|'
.. edit_message .. '|8px|baseline|class=noviewer|link=https://www.wikidata.org/wiki/'
.. item.id .. '#P31' .. ']]</sup>')
if #statements >= math.max(list_length-3,3) and lang == 'sv' then -- warning of long list but not too long list
wikicategory = wikicategory .. '[[Kategori:Databox med lång lista]]'
end
end
end
local properties = mw.wikibase.orderProperties(item:getProperties())
local property_blacklist_hash = Set(property_blacklist)
property_blacklist_hash['P18'] = true --Showed separately
property_blacklist_hash['P31'] = true --Showed separately
local property_whitelist_hash = Set(property_whitelist)
local properties_with_parents_hash = Set(properties_with_parents)
local properties_with_children_hash = Set(properties_with_children)
local countryid = ' '
pcall(function ()
countryid = item.claims['P17'][1].mainsnak.datavalue.value.id
end)
for _, property in pairs(properties) do
local datatype = item.claims[property][1].mainsnak.datatype
local statements = item:getBestStatements(property)
if ( (datatype ~= 'external-id'
and datatype ~= 'commonsMedia'
and datatype ~= 'url')
or property_whitelist_hash[property] )
and not property_blacklist_hash[property]
and 1 <= #statements then
if #statements > list_length then
if lang == 'sv' then
wikicategory = wikicategory .. '[[Kategori:Databox med dold lång lista]]'
end
else
local propertyValue = item:formatStatements(property)
propertyValue.label = langObject:ucfirst(hyphenate(propertyValue.label, lang)) -- left table cell content
local propertyEntity = mw.wikibase.getEntity(property) -- Time consuming
if propertyEntity then
-- Replace property name by short name if only one in content language:
if propertyEntity['claims']['P1813'] then
local shortNames = propertyEntity['claims']['P1813'] -- 'P1813' = short name.
shortname = ''
for _, s in pairs(shortNames) do
if s.mainsnak.snaktype == 'value'
and s.mainsnak.datavalue.value.language == lang then -- (Should check that only one value is in the content lang)
if #shortname > 0 then
shortname = ''
break -- Several shortnames in the local language
end
shortname = s.mainsnak.datavalue.value.text
end
end
if #shortname > 0 then
propertyValue.label = langObject:ucfirst(hyphenate(shortname, lang))
end
end
-- Link row label (property name) to related article in content language:
local propertySubjects = propertyEntity:getBestStatements('P1629') -- 'P1629 = subject item of this property'
if #propertySubjects == 1
and propertyEntity['claims']['P1629'][1].mainsnak.snaktype == 'value' then
local subjectItemQid = propertyEntity['claims']['P1629'][1].mainsnak.datavalue.value.id
articleSitelink = mw.wikibase.getSitelink(subjectItemQid)
if articleSitelink ~= nil then -- Property subject item has local article
propertyValue.label = '[[' .. articleSitelink .. '|' .. propertyValue.label .. ']]'
end
end
end
local dataValues -- right table cell content
if #statements == 1
and levels >= 2
and (properties_with_parents_hash[property]
or properties_with_children_hash[property])
then
dataValues = propertyValue.value
if merged_chronology and property == 'P156' then -- If 'P155' (follows) already shown as bulleted list, P156 (followed by) should be part of same list.
propertyValue.label = '' -- Hide 'Followed by' in left column
end
if property == 'P155' or property == 'P156' then -- follows or followed by
dataValues = '• ' .. dataValues
end
local level = {}
-- Show parent/child item if any:
if item['claims'][property][1].mainsnak.snaktype == 'value' then
level[1] = {}
level[1].value = item['claims'][property][1].mainsnak.datavalue.value -- (Can give non-best statement?)
level[1].item = mw.wikibase.getEntity(level[1].value.id) -- Time consuming
level[1].statements = mw.wikibase.getBestStatements(level[1].item.id, property)
end
if item['claims'][property][1].mainsnak.snaktype == 'value'
and #level[1].statements == 1 and level[1].statements[1].mainsnak.datavalue then
level[1].qid = level[1].statements[1].mainsnak.datavalue.value.id
if level[1].qid ~= countryid then -- do not repeat country as administrative belonging or place
level[1].propertyValue = level[1].item:formatStatements(property)
if level[1].propertyValue then
-- Show multi-level list as bulleted list:
if not (property == 'P155' or property == 'P156') then
dataValues = '• ' .. dataValues
end
level[1].qid = level[1].statements[1].mainsnak.datavalue.value.id
if properties_with_children_hash[property] then -- next lower level / child item: put in end of the list.
if property == 'P156' then -- follows
dataValues = dataValues
.. '<br/>• ' .. level[1].propertyValue.value
else -- indent
dataValues = dataValues
.. '<br/>' .. ' • ' .. level[1].propertyValue.value
end
else -- next higher level / parent item: put first in list
if property == 'P155' then -- followed by
dataValues = '• ' .. level[1].propertyValue.value
.. '<br/>' .. dataValues
else -- indent
dataValues = '• ' .. level[1].propertyValue.value
.. '<br/> ' .. dataValues
end
end
local lc = 2 -- level counter
while lc<levels and level[lc-1].item.claims[property][1].mainsnak.datavalue do
level[lc]={}
level[lc].value = level[lc-1].item.claims[property][1].mainsnak.datavalue.value -- (Best statement?)
level[lc].item = mw.wikibase.getEntity(level[lc].value.id) -- Time consuming
level[lc].statements = mw.wikibase.getBestStatements(level[lc].item.id, property)
if #level[lc].statements > 0 and level[lc].statements[1].mainsnak.datavalue then
level[lc].qid = level[lc].statements[1].mainsnak.datavalue.value.id
if #level[lc].statements == 1
and level[lc].qid ~= countryid -- do not repeat country as administrative belonging or place
then
level[lc].propertyValue = level[lc].item:formatStatements(property) -- (Best statement?)
if properties_with_children_hash[property] then -- next lower level / child item
if property == 'P156' then -- follows
dataValues = dataValues .. '<br/>'
.. '• ' .. level[lc].propertyValue.value
else -- indent
dataValues = dataValues .. '<br/>'
.. string.rep(' ', lc) .. '• ' .. level[lc].propertyValue.value
end
else -- next higher level / parent item
if property == 'P155' then -- followed by
dataValues = '• ' .. level[lc].propertyValue.value
.. '<br/>' .. dataValues
else -- indent
dataValues = '• ' .. level[lc].propertyValue.value
.. '<br/> ' .. dataValues:gsub('<br/>', '<br/> ')
end
end
lc = lc+1
else
break
end
else
break
end
end -- while lc
if lang == 'sv' then
wikicategory = wikicategory .. '[[Kategori:Databox med ' .. lc .. ' nivåer]]'
end
end
end
end
if property == 'P155' then -- P155 (follows) was a bulleted list
if level[1] then
followed_by = mw.wikibase.getBestStatements(level[1].item.id, 'P156')
if followed_by and #followed_by == 1 then -- P156 (followed by) may also be a bulleted list
-- Show merged chronology list, including this wikidata object
dataValues = dataValues
.. "<p>• \'\'\'" .. item:getLabel() .. "\'\'\'"
if lang == 'da' or lang == 'sv' then
propertyValue.label = 'Kronologi'
merged_chronology = true
end
if lang == 'en' then
propertyValue.label = 'Chronology'
merged_chronology = true
end
end
end
end
else -- not a multi-level list
if datatype == 'url' then -- only show first url
if statements[1].mainsnak.snaktype == 'value' then
if #statements[1].mainsnak.datavalue.value>40 then -- replace long url by "link"
if lang == 'sv' then
dataValues = frame:preprocess('[' .. statements[1].mainsnak.datavalue.value .. ' länk]')
else
dataValues = frame:preprocess('[' .. statements[1].mainsnak.datavalue.value .. ' link]')
end
else -- hide "https://" or "http:// and / in the end"
dataValues = frame:preprocess('[' .. statements[1].mainsnak.datavalue.value
.. ' ' .. statements[1].mainsnak.datavalue.value:gsub('https?://', ''):gsub('/$', '') .. ']')
end
end
elseif datatype == 'geo-shape' then -- only show first geo-shape
if lang == 'sv' then
dataValues = frame:preprocess('[https://commons.wikimedia.org/wiki/'
.. statements[1].mainsnak.datavalue.value:gsub(' ', '_') .. ' kartlänk]')
else
dataValues = frame:preprocess('[https://commons.wikimedia.org/wiki/'
.. statements[1].mainsnak.datavalue.value:gsub(' ', '_') .. ' link]')
end
elseif datatype == 'monolingualtext' then
for _, s in pairs(statements) do
if s.mainsnak.snaktype == 'value'
and s.mainsnak.datavalue.value.language == lang then
dataValues = frame:preprocess(s.mainsnak.datavalue.value)
if lang == 'sv' then
wikicategory = wikicategory .. '[[Kategori:Databox med monolingualtext]]'
end
break -- Maximum one monolingualtext per property
end
end
else
dataValues = frame:preprocess(propertyValue.value)
if #statements > 1 then
dataValues = listSeparate(dataValues, list_separator)
end
if datatype == 'time' then
dataValues = year(dataValues, lang, replaceTime)
end
if #statements >= math.max(list_length-3,3)
and lang == 'sv' then --Warning on long but not hidden list
wikicategory = wikicategory .. '[[Kategori:Databox med lång lista]]'
end
end
end
-- Replace "no value" with a dash:
if dataValues and noValueDict[lang] then
dataValues = dataValues:gsub('<span>' .. noValueDict[lang] .. '</span>', '<span>–</span>')
end
-- Render table row:
if dataValues and dataValues ~= '<span>–</span>' then
dataTable:tag('tr')
:tag('th')
:css({
['vertical-align'] = 'text-top',
})
:attr('scope', 'row')
:attr('colspan', '1')
:wikitext(frame:preprocess(propertyValue.label)):done()
:tag('td')
:css({
['vertical-align'] = 'text-top',
})
:attr('colspan', '2')
:wikitext(dataValues)
:wikitext('<sup class="noprint Inline-Template"> [[File:Arbcom_ru_editing.svg|'
.. edit_message .. '|8px|baseline|class=noviewer|link=https://www.wikidata.org/wiki/'
.. item.id .. '#' .. property .. ']]</sup>')
end -- if dataValues
end -- if #statements
end -- if datatype
end -- for property
--Automatic coordinate location map(s)
if zoom >= 0 then
local coordinates_statements = item:getBestStatements('P625') -- P625 is coordinate location
local cnt = 0
for _, s in pairs(coordinates_statements) do
if s.mainsnak.datavalue and s.mainsnak.datavalue.value.globe == 'http://www.wikidata.org/entity/Q2' then
cnt = cnt + 1
databoxRoot:wikitext(buildInteractiveMap(width, s.mainsnak.datavalue.value, item.id, zoom))
if lang == 'sv' then
if cnt == 1 then
wikicategory = wikicategory .. '[[Kategori:Sidor med kartor skapade med Databox]]' .. ' '
else
wikicategory = wikicategory .. '[[Kategori:Sidor med flera kartor skapade med Databox]]' .. ' '
end
end
end
if cnt >= maxFiles then
break -- Show maximum maxFiles maps or coordinates.
end
end -- for
end
--Other commonsMedia files: show first good file for each property that have media legend in content language
if tonumber(height) > 0 then
for _, property in pairs(properties) do
local datatype = item.claims[property][1].mainsnak.datatype
local statements = item:getBestStatements(property)
if (datatype == 'commonsMedia')
and not property_blacklist_hash[property]
and property ~= 'P18' then -- Image showed separately
local files = item:getBestStatements(property)
if #files >= 1 then
local file
local caption
for _, i in pairs(files) do
if i.qualifiers then
if i.qualifiers.P2096 then -- P2096 is 'caption'
for _, q in pairs(i.qualifiers.P2096) do
if q.snaktype == 'value' and q.datavalue.value.language == lang then
caption = q
file = i
break
end
end
elseif langId and i.qualifiers.P407 then -- P407 is 'language of work or name'
for _, q in pairs(i.qualifiers.P407) do
if q.snaktype == 'value'
and q.datavalue.value.id == langId -- local language
then
file = i
break
end
end
end
end -- if i.qualifiers
if file then
break
end
end -- for _, i in pairs(files)
if file then
if caption then
databoxRoot
:tag('div')
:css({
['text-align'] = 'center',
padding = '0.0em 0.4',
})
:wikitext('[[File:' .. file.mainsnak.datavalue.value .. '|frameless|'
.. width .. 'x' .. height .. 'px]]')
databoxRoot
:tag('div')
:css({
['text-align'] = 'center',
['font-size'] = '90%',
['line-height'] = '140%',
['padding-bottom'] = '0.5em',
})
:wikitext(caption.datavalue.value.text)
:wikitext('<sup class="noprint Inline-Template"> [[File:Arbcom_ru_editing.svg|'
.. edit_message .. '|8px|baseline|class=noviewer|link=https://www.wikidata.org/wiki/'
.. item.id .. '#' .. property .. ']]</sup>')
else -- no caption
databoxRoot
:tag('div')
:css({
['text-align'] = 'center',
padding = '0.0em 0.4',
})
:wikitext('[[File:' .. file.mainsnak.datavalue.value .. '|frameless|'
.. width .. 'x' .. height .. 'px]]')
databoxRoot
:tag('div')
:css({
['text-align'] = 'center',
['font-size'] = '90%',
['line-height'] = '140%',
['padding-bottom'] = '0.5em',
})
end -- if caption
if lang == 'sv' then
if property == 'P242' then -- P242 is 'locator map image'
wikicategory = wikicategory .. '[[Kategori:Sidor med översiktskartor skapade med Databox]]' .. ' '
else
wikicategory = wikicategory .. '[[Kategori:Sidor med andra mediafiler i Databox]]' .. ' '
end
end
end -- if file
end -- if #files
end -- if datatype
end -- for _, property
end -- if height
--Category
if mw.title.getCurrentTitle().namespace == 0 then -- Only in main namespace
if tostring(databoxRoot):match('<span>Q%d+</span>') then
if lang == 'da' then
wikicategory = wikicategory .. '[[Kategori:Databox der viser Qid-kode]]' .. ' '
elseif lang == 'sv' then
wikicategory = wikicategory .. '[[Kategori:Databox som visar qid-kod]]' .. ' '
elseif lang == 'en' then
wikicategory = wikicategory .. '[[Category:Databox that shows qid code]]' .. ' '
elseif lang == 'frr' then
wikicategory = wikicategory .. '[[Kategorie:Databox mit Qid-Code]]' .. ' '
end
end
if #wikicategory then
databoxRoot:wikitext(wikicategory)
end
end
if #dump then
databoxRoot:wikitext(dump)
end
return tostring(databoxRoot)
end -- function
return p