Spring til indhold

Modul:Databox: Forskelle mellem versioner

Fra Wikipedia, den frie encyklopædi
Indhold slettet Indhold tilføjet
Dansk orddeling
Parameter "keep_title_case" to not change first letter to upper case (default false)
 
(5 mellemliggende versioner af 3 andre brugere ikke vist)
Linje 1: Linje 1:
-- This extended version of Databox is stored at https://sv.wikipedia.org/wiki/Modul:Databox, but can be used by other languages
-- 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)
-- 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
-- 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 any commonsMedia file that has media caption qualifier in the local language, or with content in ("language of work" qualifier) the local language
Linje 9: Linje 10:
-- 2020-05-24 Years linked to articles. Decades, centuries and millennia formated in local language.
-- 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.
-- 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.
-- 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.
-- 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).
-- 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-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-02 More than two parent/child levels in bulleted list.
-- 2020-05-01 Property short names based on P1813. Image legend/caption.
-- 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).
-- 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".
-- 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-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-21 Parameters "width", "height", "zoom" and "list_length". Soft hyphens auto-inserted in long property names.
Linje 27: Linje 28:
-- Blocked properties:
-- Blocked properties:
local property_blacklist = {
local property_blacklist = {
'P360', --is a list of
'P360', --is a list of
'P4224', --category contains
'P4224', --category contains
'P935', -- Commons gallery
'P935', -- Commons gallery
'P1472', -- Commons Creator page
'P1472', -- Commons Creator page
'P1612', -- Commons Institution page
'P1612', -- Commons Institution page
'P373', -- Commons category
'P373', -- Commons category
'P3722', -- Commons maps category
'P3722', -- Commons maps category
'P7561', -- for the interior of the item
'P7561', -- for the interior of the item
'P1151', -- topic's main Wikimedia portal
'P1151', -- topic's main Wikimedia portal
'P1424', -- topic's main template
'P1424', -- topic's main template
'P910', -- topic's main category
'P910', -- topic's main category
'P1200', -- bodies of water basin category
'P1200', -- bodies of water basin category
'P1792', -- category of associated people
'P1792', -- category of associated people
'P1464', -- category for people born here
'P1464', -- category for people born here
'P1465', -- category for people who died here
'P1465', -- category for people who died here
'P1791', -- category of people buried here
'P1791', -- category of people buried here
'P1740', -- category for films shot at this location
'P1740', -- category for films shot at this location
'P2033', -- Category for pictures taken with camera
'P2033', -- Category for pictures taken with camera
'P2517', -- category for recipients of this award
'P2517', -- category for recipients of this award
'P4195', -- category for employees of the organization
'P4195', -- category for employees of the organization
'P1754', -- category related to list
'P1754', -- category related to list
'P301', -- category's main topic
'P301', -- category's main topic
'P971', -- category combines topics
'P971', -- category combines topics
'P3876', -- category for alumni of educational institution
'P3876', -- category for alumni of educational institution
'P1753', -- list related to category
'P1753', -- list related to category
'P7867', -- category for maps
'P7867', -- category for maps
'P1921', -- Wikidata RDF URI format
'P1921', -- Wikidata RDF URI format
'P3921', -- Wikidata SPARQL query equivalent
'P3921', -- Wikidata SPARQL query equivalent
'P1204', -- Wikimedia portal's main topic
'P1204', -- Wikimedia portal's main topic
'P1423', -- template's main topic
'P1423', -- template's main topic
'P1709', -- equivalent class
'P1709', -- equivalent class
'P3950', -- narrower external class
'P3950', -- narrower external class
'P2888', -- exact match
'P2888', -- exact match
'P1382', -- coincident with
'P1382', -- coincident with
'P2670', -- has parts of the class
'P2670', -- has parts of the class
'P3113', -- does not have part
'P3113', -- does not have part
'P2737', -- union of
'P2737', -- union of
'P2738', -- disjoint union of
'P2738', -- disjoint union of
'P2445', -- metasubclass of
'P2445', -- metasubclass of
'P1963', -- properties for this type
'P1963', -- properties for this type
'P3176', -- uses property
'P3176', -- uses property
'P1889', -- different from
'P1889', -- different from
'P460', -- said to be the same as
'P460', -- said to be the same as
'P2959', -- permanent duplicated item
'P2959', -- permanent duplicated item
'P2860', -- cites
'P2860', -- cites
'P5125', -- wikimedia outline
'P5125', -- wikimedia outline
'P5008', -- on focus list of Wikimedia project
'P5008', -- on focus list of Wikimedia project
'P7084', -- related category
'P7084', -- related category
'P1687', -- Wikidata main property for this item
'P1687', -- Wikidata main property for this item
'P2559', -- Wikidata usage instructions
'P2559', -- Wikidata usage instructions
'P5692', -- Wikidata dummy value
'P5692', -- Wikidata dummy value
'P1343', -- described by source
'P1343', -- described by source
'P972', -- catalogue
'P972', -- catalogue
'P1282', -- OSM tag or key
'P1282', -- OSM tag or key
'P553', -- web site account
'P553', -- web site account
'P968', -- email
'P968', -- email
'P2572', -- hashtag
'P2572', -- hashtag
'P3761', -- IPv4 range
'P3761', -- IPv4 range
'P4839', -- Wolfram Language entity code
'P4839', -- Wolfram Language entity code
'P6104', -- Maintained by Wikiproject
'P6104', -- Maintained by Wikiproject
'P5996', -- Category for films in this language
'P5996', -- Category for films in this language
'P2354', -- list article (seldom available in local language)
'P2354', -- list article (seldom available in local language)
'P6365', -- member category
'P6365', -- member category
'P528', -- catalog code
'P528', -- catalog code
'P667', -- ICPC 2 ID
'P667', -- ICPC 2 ID
'P944', -- Code of nomenclature
'P944', -- Code of nomenclature
'P1438', -- Jewish Encyclopedia ID (Russian)e
'P1438', -- Jewish Encyclopedia ID (Russian)e
'P1402', -- Foundational Model of Anatomy ID
'P1402', -- Foundational Model of Anatomy ID
'P1461', -- Patientplus ID
'P1461', -- Patientplus ID
'P1692', -- ICD-9-CM code
'P1692', -- ICD-9-CM code
'P1748', -- NCI Thesaurus ID
'P1748', -- NCI Thesaurus ID
'P1193', -- prevalence (often different value in different countries)
'P1193', -- prevalence (often different value in different countries)
'P2176', -- drug used for treatment (we avoid medical advise)
'P2176', -- drug used for treatment (we avoid medical advise)
'P2293', -- genetic association
'P2293', -- genetic association
'P1814', -- Japanese name in kana
'P1814', -- Japanese name in kana
'P747', -- editions
'P747', -- editions
'P1433', -- published in
'P1433', -- published in
'P4969', -- derivative work
'P4969', -- derivative work
'P217', -- inventory number
'P217', -- inventory number
'P2540', -- Aarne–Thompson–Uther Tale Type Index
'P2540', -- Aarne–Thompson–Uther Tale Type Index
'P1036', -- DDC
'P1036', -- DDC
'P1149', -- LCC
'P1149', -- LCC
'P1150', -- RVK
'P1150', -- RVK
'P1190', -- UDC
'P1190', -- UDC
'P1987', -- MCN code
'P1987', -- MCN code
'P2263', -- ISOCat id
'P2263', -- ISOCat id
'P2283', -- Uses
'P2283', -- Uses
'P2184', -- History of subject. (Should be shown if article in local language)
'P2184', -- History of subject. (Should be shown if article in local language)
'P989', -- spoken text. (Should be shown if in local language)
'P989', -- spoken text. (Should be shown if in local language)
'P1793', -- format as a regex
'P1793', -- format as a regex
'P4354', -- search formatter URL
'P4354', -- search formatter URL
'P5869', -- model item
'P5869', -- model item
'P859', -- sponsor
'P859', -- sponsor
'P7973', -- quantity symbol (LaTeX)
'P7973', -- quantity symbol (LaTeX)
'P6216', -- copyright status
'P6216', -- copyright status
'P1830', -- owner of (seldom useful)
'P1830', -- owner of (seldom useful)
'P487', -- Unicode character
'P487', -- Unicode character
'P8933', -- category for the view from the item
'P8933', -- category for the view from the item
'P1299', -- depicted by
'P1299', -- depicted by
'P6112', -- category for members of a team
'P6112', -- category for members of a team
'P8687', -- social media followers
'P8687', -- social media followers
'P1559', -- name in native language
'P1559', -- name in native language
'P8596', -- category for multimedia files depicting exterior views of this item
'P8596', -- category for multimedia files depicting exterior views of this item
'P7763', -- copyright status as a creator
'P7763', -- copyright status as a creator
'P8989', -- category for the view of the item
'P8989', -- category for the view of the item
'P7782' -- category for ship name
'P7782', -- category for ship name
'P2817', -- appears in the heritage monument list
'P8402' -- open data portal
}
}


Linje 140: Linje 143:
'P3896',-- geoshape
'P3896',-- geoshape
'P345', -- IMDB id
'P345', -- IMDB id
'P6375' -- street address
'P6375' -- street address
}
}


Linje 154: Linje 157:
'P706', -- located on terrain feature
'P706', -- located on terrain feature
'P749', -- parent organization
'P749', -- parent organization
'P1647' -- subproperty of
'P807', -- separated/forked from
'P1365', -- replaced
'P1647', -- subproperty of
'P3730' -- next higher rank
}
}


Linje 164: Linje 170:
'P527', -- has part
'P527', -- has part
'P1012', -- contains
'P1012', -- contains
'P4330' -- contains
'P1366', -- replaced by
'P3729', -- next lower rank
'P4330', -- contains
'P7888' -- merged into
}
}


local function buildInteractiveMap(width, point, item_id, zoom)
local function buildInteractiveMap(width, point, item_id, zoom)
--Utility function to build maps
--Utility function to build maps
local geojson = {
local geojson = {
{
{
type = 'Feature',
type = 'Feature',
geometry = {
geometry = {
type = "Point",
type = "Point",
coordinates = { point.longitude, point.latitude }
coordinates = {point.longitude, point.latitude}
},
},
properties = {
properties = {
title = point.text or '',
title = point.text or '',
['marker-symbol'] = point.marker or 'marker',
['marker-symbol'] = point.marker or 'marker',
['marker-color'] = point.markercolor or "#224422",
['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. )
}
}
local args = {
return mw.getCurrentFrame():extensionTag('mapframe', mw.text.jsonEncode(geojson), 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
end


Linje 207: Linje 216:
-- Capitalizes first visible character of list produced by formatStatements()
-- Capitalizes first visible character of list produced by formatStatements()
-- Example: <span><span>[[link|first item]]</span>, <span>second item</span></span>
-- Example: <span><span>[[link|first item]]</span>, <span>second item</span></span>
-- --> <span><span>[[link|First item]]</span>, <span>second item</span></span>
-- --> <span><span>[[link|First item]]</span>, <span>second item</span></span>
return str
return str
:gsub('^<span><span>%[%[(.-)|(.-)%]%]</span>',
:gsub('^<span><span>%[%[(.-)|(.-)%]%]</span>',
Linje 225: Linje 234:
-- Example: list_separator = ';<br>'
-- Example: list_separator = ';<br>'
-- str = <span><span>[[link|first item]]</span>, <span>second item</span></span>
-- str = <span><span>[[link|first item]]</span>, <span>second item</span></span>
-- -> <span><span>[[link|first item]]</span>;<br> <span>second item</span></span>
-- -> <span><span>[[link|first item]]</span>;<br> <span>second item</span></span>
if list_separator ~= ',' then
if list_separator ~= ',' then
return str
return str
Linje 237: Linje 246:
-- Inserts soft hyphens in long words, typically before each consonant that is followed by a vowel (lower-case letters)
-- 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.
-- Should work good enough for most languages. Language specific exceptions may be added.
local nonHyphenatedLanguages = Set{ 'ar', 'he', 'zh', 'ja', 'ko', 'vi', 'fa', 'ps' }
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
if nonHyphenatedLanguages[lang] then -- Not languages without alphabetic writing system or with few vowels
return str
return str
Linje 260: Linje 269:
:gsub("ss&shy;j", "s&shy;sj")-- Example: ss-j-> s-sj
:gsub("ss&shy;j", "s&shy;sj")-- Example: ss-j-> s-sj
:gsub("n&shy;g", "ng&shy;") -- Example: n-g -> ng-
:gsub("n&shy;g", "ng&shy;") -- Example: n-g -> ng-
:gsub("ng&shy;s", "ngs&shy;") -- Example: Befolk-ning-sg-ruppe -> Befolk-nings-g-ruppe, Rege-ring-s-che-fens -> Rege-rings-chefens
:gsub("ngs", "ngs&shy;") -- Example: Befolk-ningsg-rup-pe -> Befolk-nings-g-rup-pe, Rege-ring-s-che-fens -> Rege-rings-chefens
:gsub("g&shy;rup&shy;pe", "&shy;gruppe") -- Example: g-rup-pe -> -gruppe
:gsub("nist&shy;ra", "nis&shy;tra") -- Example: admi-nist-ra-tion -> admi-nis-tra-tion
:gsub("nist&shy;ra", "nis&shy;tra") -- Example: admi-nist-ra-tion -> admi-nis-tra-tion
:gsub("&shy;ror&shy;ga[&shy;]*n", "r&shy;organ") -- Example: dotte-ror-ga-ni-sa-tion -> dotter-organi-sa-tion
:gsub("&shy;ror&shy;ga[&shy;]*n", "r&shy;organ") -- Example: dotte-ror-ga-ni-sa-tion -> dotter-organi-sa-tion
Linje 274: Linje 284:
:gsub("gars&shy;kap", "gar&shy;skap") -- Example: medbor-gars-kap -> medbor-gar-skap
:gsub("gars&shy;kap", "gar&shy;skap") -- Example: medbor-gars-kap -> medbor-gar-skap
:gsub("k&shy;var&shy;ter", "&shy;kvarter") -- Example: Hovedk-var-ter -> Hoved-kvarter
:gsub("k&shy;var&shy;ter", "&shy;kvarter") -- Example: Hovedk-var-ter -> Hoved-kvarter
:gsub("s&shy;ted", "&shy;sted") -- Example: Pro-duk-tionss-ted -> Pro-duk-tions-sted
:gsub("&shy;&shy;", "&shy;") -- Example -- -> -
end
end
end
end
Linje 304: Linje 316:
if lang=='sv' then
if lang=='sv' then
str = str
str = str
:gsub("(%d?1%d)%.? år([h|t])(%a+)det?", "%1:e år%2%3det") -- 12. årtusende -> 12:e årtusendet
: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?[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("(%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</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("<span>(%d?%d?%d?)00-talet ([%a%.]*)</span>", "<span>[[%100-talet (decennium) %2]]</span>") -- 100-talet f.Kr. -> [[100-talet f.Kr. (decennium)]]
Linje 328: Linje 340:


function p.databox(frame)
function p.databox(frame)
local args = frame:getParent().args
local args = frame:getParent().args
local itemId = nil
local itemId = nil
if args.item then
if args.item then
itemId = args.item
itemId = args.item
end
end
local item = mw.wikibase.getEntity(itemId)
local item = mw.wikibase.getEntity(itemId)
if item == nil then
if item == nil then
mw.addWarning("Wikidata item not found")
mw.addWarning("Wikidata item not found")
return ""
return ""
end
end
local width = '260' -- default max width of template, image and map, and height of map
local width = '260' -- default max width of template, image and map, and height of map
if args.width then
if args.width then
width = args.width
width = args.width
end
end
local height = '240' -- default max height of image. hidden if <= 0.
local height = '240' -- default max height of image. hidden if <= 0.
if args.height then
if args.height then
height = args.height
height = args.height
end
end
local zoom = 12 -- default map zoom level. hidden if <0.
local zoom = 12 -- default map zoom level. hidden if <0.
if args.zoom then
if args.zoom then
zoom = tonumber(args.zoom)
zoom = tonumber(args.zoom)
end
end
local list_length = 8 -- default max no of values in lists
local list_length = 8 -- default max no of values in lists
if args.list_length then
if args.list_length then
list_length = tonumber(args.list_length)
list_length = tonumber(args.list_length)
end
end
local list_separator = ',' -- default no replacement of comma in lists
local list_separator = ',' -- default no replacement of comma in lists
if args.list_separator then
if args.list_separator then
list_separator = args.list_separator
list_separator = args.list_separator
end
end
local levels = 3 -- default max no of child and parent levels
local levels = 3 -- default max no of child and parent levels
if args.levels then
if args.levels then
levels = tonumber(args.levels)
levels = tonumber(args.levels)
end
end
local maxFiles = 1 -- default max no of coordinate location maps
local maxFiles = 1 -- default max no of coordinate location maps
if args.maxFiles then
if args.maxFiles then
maxFiles = tonumber(args.maxFiles)
maxFiles = tonumber(args.maxFiles)
end
end
local langObject = mw.language.getContentLanguage()
local langObject = mw.language.getContentLanguage()
local lang = langObject:getCode()
local lang = langObject:getCode()


local langIdDict = { -- Dictionary for translating language code to language Wikidata item id
local langIdDict = { -- Dictionary for translating language code to language Wikidata item id
['af'] = 'Q14196',
['af'] = 'Q14196',
['atj'] = 'Q56590',
['be-tarask'] = 'Q8937989',
['ca'] = 'Q7026',
['ca'] = 'Q7026',
['ceb'] = 'Q33239',
['ckb'] = 'Q36811',
['cs'] = 'Q9056',
['cs'] = 'Q9056',
['da'] = 'Q9035',
['da'] = 'Q9035',
['dag'] = 'Q32238',
['de'] = 'Q188',
['de'] = 'Q188',
['en'] = 'Q1860',
['en'] = 'Q1860',
['es'] = 'Q1321',
['es'] = 'Q1321',
['ewe'] = 'Q30005',
['fi'] = 'Q1412',
['fi'] = 'Q1412',
['fa'] = 'Q9168',
['fa'] = 'Q9168',
['fr'] = 'Q150',
['fr'] = 'Q150',
['frr'] = 'Q28224',
['haw'] = 'Q33569',
['he'] = 'Q9288',
['he'] = 'Q9288',
['hi'] = 'Q1568',
['hi'] = 'Q1568',
['it'] = 'Q652',
['it'] = 'Q652',
['ja'] = 'Q5287',
['ja'] = 'Q5287',
['kab'] = 'Q35853',
['ko'] = 'Q9176',
['ko'] = 'Q9176',
['mzn'] = 'Q13356',
['nap'] = 'Q33845',
['nds'] = 'Q25433',
['nl'] = 'Q10000',
['nl'] = 'Q10000',
['no'] = 'Q9043',
['no'] = 'Q9043',
['nqo'] = 'Q18546266',
['pap'] = 'Q33856',
['pl'] = 'Q809',
['pl'] = 'Q809',
['pcm'] = 'Q33655',
['pt'] = 'Q5146',
['pt'] = 'Q5146',
['ru'] = 'Q7737',
['ru'] = 'Q7737',
['rue'] = 'Q26245',
['sh'] = 'Q9301',
['sh'] = 'Q9301',
['sv'] = 'Q9027',
['sv'] = 'Q9027',
Linje 399: Linje 427:
}
}
local dump = ''
local dump = ''
local langId -- Local language Wikidata item id
local langId -- Local language Wikidata item id
langId = langIdDict[lang] or nil
langId = langIdDict[lang] or nil


local edit_message = mw.message.new('vector-view-edit'):plain()
local edit_message = mw.message.new('vector-view-edit'):plain() .. ' Wikidata'
-- Date formating
-- Date formating
Linje 418: Linje 446:
local bce = bceDict[lang] or 'BCE'
local bce = bceDict[lang] or 'BCE'
local era = bc -- default era
local era = bc -- default era
if args.era then
if args.era then
if args.era == 'BC' then
if args.era == 'BC' then
era = bc -- replace 'BCE' by 'BC' in content language
era = bc -- replace 'BCE' by 'BC' in content language
elseif args.era == 'BCE' then
elseif args.era == 'BCE' then
era = bce -- replace 'BC' by 'BCE' in content language
era = bce -- replace 'BC' by 'BCE' in content language
else
else
era = args.era -- replace 'BCE' and 'BC' by arbitrary argument value, for example empty string
era = args.era -- replace 'BCE' and 'BC' by arbitrary argument value, for example empty string
end
end
end
end
local replaceTime = {} -- global variable
local replaceTime = {} -- global variable
replaceTime[' BCE'] = ' '..era
replaceTime[' BCE'] = ' '..era
replaceTime[' '..bce] = ' '..era
replaceTime[' '..bce] = ' '..era
Linje 438: Linje 466:
}
}
local wikicategory = ''
local wikicategory = ''
local databoxRoot = mw.html.create('div')
local databoxRoot = mw.html.create('div')
:addClass('infobox')
:addClass('infobox')
:css({
:css({
float = 'right',
float = 'right',
clear = 'right',
clear = 'right',
border = '1px solid #aaa',
border = '1px solid #aaa',
['background-color'] = '#f9f9f9',
['background-color'] = '#f9f9f9',
['width'] = width .. 'px',
['width'] = width .. 'px',
padding = '0 0.4em',
padding = '0 0.4em',
margin = '0 0 0.4em 0.4em',
margin = '0 0 0.4em 0.4em',
})
})


--Title
--Title
local title = item:getLabel() or mw.title.getCurrentTitle().text
databoxRoot:tag('div')
if args.keep_title_case == nil or #args.keep_title_case == 0 or args.keep_title_case == 'false' then
:css({
title = langObject:ucfirst(title)
['text-align'] = 'center',
end
['background-color'] = 'LightGrey',
databoxRoot:tag('div')
padding = '0em 0.4',
:css({
margin = '0em 0',
['font-size'] = '120%',
['text-align'] = 'center',
['font-weight'] = 'bold',
['background-color'] = 'LightGrey',
padding = '0em 0.4',
})
margin = '0em 0',
:wikitext( langObject:ucfirst(item:getLabel()) or langObject:ucfirst(mw.title.getCurrentTitle().text ))
['font-size'] = '120%',
['font-weight'] = 'bold',
})
:wikitext(title)


--Description
--Description
local descr, descrLang = item:getDescriptionWithLang()
local descr, descrLang = item:getDescriptionWithLang()
if descrLang == lang then -- Do not show any fallback language
if descrLang == lang then -- Do not show any fallback language
databoxRoot:tag('div')
databoxRoot:tag('div')
:css({
:css({
['text-align'] = 'center',
['text-align'] = 'center',
['vertical-align'] = 'text-top',
['vertical-align'] = 'text-top',
['font-size'] = '90%',
['font-size'] = '90%',
['line-height'] = '140%',
['line-height'] = '140%',
padding = '0.2em 0.4',
padding = '0.2em 0.4',
margin = '0.0em 0.4',
margin = '0.0em 0.4',
['padding-bottom'] = '0.5em',
['padding-bottom'] = '0.5em',
})
})
:wikitext(langObject:ucfirst(descr):sub(1,-1))
:wikitext(langObject:ucfirst(descr):sub(1,-1))
:wikitext('<sup class="noprint Inline-Template">&nbsp;[[File:Arbcom_ru_editing.svg|'
:wikitext('<sup class="noprint Inline-Template">&nbsp;[[File:Arbcom_ru_editing.svg|'
.. edit_message .. '|8px|baseline|class=noviewer|link=https://www.wikidata.org/wiki/'
.. edit_message .. '|8px|baseline|class=noviewer|link=https://www.wikidata.org/wiki/'
.. item.id .. ']]</sup>')
.. item.id .. ']]</sup>')
end
end
--Show first good image with legend/caption in content language, or first good image
--Show first good image with legend/caption in content language, or first good image
if tonumber(height) > 0 then
if tonumber(height) > 0 then
local images = item:getBestStatements('P18') -- p18 is 'image'
local images = item:getBestStatements('P18') -- p18 is 'image'
if #images >= 1 then
if #images >= 1 then
local image = images[1]
local image = images[1]
for _, i in pairs(images) do
for _, i in pairs(images) do
if i.qualifiers and i.qualifiers.P2096 then -- P2096 is 'caption'
if i.qualifiers and i.qualifiers.P2096 then -- P2096 is 'caption'
for _, c in pairs(i.qualifiers.P2096) do
for _, c in pairs(i.qualifiers.P2096) do
if c.snaktype == 'value' and c.datavalue.value.language == lang then
if c.snaktype == 'value' and c.datavalue.value.language == lang then
caption = c
caption = c
image = i
image = i
break
break
Linje 501: Linje 533:
break
break
end
end
end
end
if image.mainsnak.snaktype == 'value' then
if image.mainsnak.snaktype == 'value' then
databoxRoot
databoxRoot
:tag('div')
:tag('div')
:css({
:css({
['text-align'] = 'center',
['text-align'] = 'center',
padding = '0.0em 0.4',
padding = '0.0em 0.4',
})
})
:wikitext('[[File:' .. image.mainsnak.datavalue.value .. '|frameless|'
:wikitext('[[File:' .. image.mainsnak.datavalue.value .. '|frameless|'
.. width .. 'x' .. height .. 'px]]')
.. width .. 'x' .. height .. 'px]]')
if caption then
if caption then
databoxRoot
databoxRoot
:tag('div')
:tag('div')
:css({
:css({
['text-align'] = 'center',
['text-align'] = 'center',
['font-size'] = '90%',
['font-size'] = '90%',
['line-height'] = '140%',
['line-height'] = '140%',
['padding-bottom'] = '0.5em',
['padding-bottom'] = '0.5em',
})
})
:wikitext(caption.datavalue.value.text)
:wikitext(caption.datavalue.value.text)
:wikitext('<sup class="noprint Inline-Template">&nbsp;[[File:Arbcom_ru_editing.svg|'
:wikitext('<sup class="noprint Inline-Template">&nbsp;[[File:Arbcom_ru_editing.svg|'
.. edit_message .. '|8px|baseline|class=noviewer|link=https://www.wikidata.org/wiki/'
.. edit_message .. '|8px|baseline|class=noviewer|link=https://www.wikidata.org/wiki/'
.. item.id .. '#' .. 'P18' .. ']]</sup>')
.. item.id .. '#' .. 'P18' .. ']]</sup>')
end
end
end
end
end
end
end
end
--Table:
--Table:
local dataTable = databoxRoot
local dataTable = databoxRoot
:tag('table')
:tag('table')
:css({
:css({
['text-align'] = 'left',
['text-align'] = 'left',
['font-size'] = '90%',
['font-size'] = '90%',
['line-height'] = '140%',
['line-height'] = '140%',
['hyphens'] = 'auto', -- works only in some browsers and languages
['hyphens'] = 'auto', -- works only in some browsers and languages
['word-break'] = 'break-word',
['word-break'] = 'break-word',
['width'] = '100%',
['width'] = '100%',
['table-layout'] = 'fixed',
['table-layout'] = 'fixed',
['padding-bottom'] = '0.5em',
['padding-bottom'] = '0.5em',
})
})
--Instance of:
--Instance of:
local dataValues
local dataValues
local statements = item:getBestStatements('P31')
local statements = item:getBestStatements('P31')
if #statements > list_length then -- Hide too long list of values
if #statements > list_length then -- Hide too long list of values
if lang == 'sv' then
if lang == 'sv' then
wikicategory = wikicategory .. '[[Kategori:Databox med dold lång lista]]'
wikicategory = wikicategory .. '[[Kategori:Databox med dold lång lista]]'
end
end
elseif #statements >= 1 then
elseif #statements >= 1 then
dataValues=item:formatStatements('P31').value
dataValues=item:formatStatements('P31').value
if lang == 'sv' then
if lang == 'sv' then
Linje 574: Linje 606:
dataValues=listCase(dataValues)
dataValues=listCase(dataValues)
dataTable:tag('caption')
dataTable:tag('caption')
:css({
:css({
['background-color'] = 'LightGrey',
['background-color'] = 'LightGrey',
['font-weight'] = 'bold',
['font-weight'] = 'bold',
['margin-top'] = '0.4em',
['margin-top'] = '0.4em',
margin = '0.5em 0',
margin = '0.5em 0',
padding = '1em 1',
padding = '1em 1',
})
})
:wikitext(dataValues)
:wikitext(dataValues)
:wikitext('<sup class="noprint Inline-Template">&nbsp;[[File:Arbcom_ru_editing.svg|'
:wikitext('<sup class="noprint Inline-Template">&nbsp;[[File:Arbcom_ru_editing.svg|'
.. edit_message .. '|8px|baseline|class=noviewer|link=https://www.wikidata.org/wiki/'
.. edit_message .. '|8px|baseline|class=noviewer|link=https://www.wikidata.org/wiki/'
.. item.id .. '#P31' .. ']]</sup>')
.. 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
if #statements >= math.max(list_length-3,3) and lang == 'sv' then -- warning of long list but not too long list
Linje 593: Linje 625:
end
end
local properties = mw.wikibase.orderProperties(item:getProperties())
local properties = mw.wikibase.orderProperties(item:getProperties())
local property_blacklist_hash = Set(property_blacklist)
local property_blacklist_hash = Set(property_blacklist)
property_blacklist_hash['P18'] = true --Showed separately
property_blacklist_hash['P18'] = true --Showed separately
property_blacklist_hash['P31'] = true --Showed separately
property_blacklist_hash['P31'] = true --Showed separately
local property_whitelist_hash = Set(property_whitelist)
local property_whitelist_hash = Set(property_whitelist)
local properties_with_parents_hash = Set(properties_with_parents)
local properties_with_parents_hash = Set(properties_with_parents)
local properties_with_children_hash = Set(properties_with_children)
local properties_with_children_hash = Set(properties_with_children)
local countryid = ' '
local countryid = ' '
pcall(function ()
pcall(function ()
countryid = item.claims['P17'][1].mainsnak.datavalue.value.id
countryid = item.claims['P17'][1].mainsnak.datavalue.value.id
end)
end)


for _, property in pairs(properties) do
for _, property in pairs(properties) do
local datatype = item.claims[property][1].mainsnak.datatype
local datatype = item.claims[property][1].mainsnak.datatype
local statements = item:getBestStatements(property)
local statements = item:getBestStatements(property)
if ( (datatype ~= 'external-id'
if ( (datatype ~= 'external-id'
and datatype ~= 'commonsMedia'
and datatype ~= 'commonsMedia'
and datatype ~= 'url')
and datatype ~= 'url')
or property_whitelist_hash[property] )
or property_whitelist_hash[property] )
and not property_blacklist_hash[property]
and not property_blacklist_hash[property]
and 1 <= #statements then
and 1 <= #statements then
if #statements > list_length then
if #statements > list_length then
if lang == 'sv' then
if lang == 'sv' then
wikicategory = wikicategory .. '[[kategori:Databox med dold lång lista]]'
wikicategory = wikicategory .. '[[Kategori:Databox med dold lång lista]]'
end
end
else
else
local propertyValue = item:formatStatements(property)
local propertyValue = item:formatStatements(property)
propertyValue.label = langObject:ucfirst(hyphenate(propertyValue.label, lang)) -- left table cell content
propertyValue.label = langObject:ucfirst(hyphenate(propertyValue.label, lang)) -- left table cell content
local propertyEntity = mw.wikibase.getEntity(property) -- Time consuming
local propertyEntity = mw.wikibase.getEntity(property) -- Time consuming
if propertyEntity then
if propertyEntity then
-- Replace property name by short name if only one in content language:
-- Replace property name by short name if only one in content language:
if propertyEntity['claims']['P1813'] then
if propertyEntity['claims']['P1813'] then
local shortNames = propertyEntity['claims']['P1813'] -- 'P1813' = short name.
local shortNames = propertyEntity['claims']['P1813'] -- 'P1813' = short name.
shortname = ''
shortname = ''
for _, s in pairs(shortNames) do
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 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
if #shortname > 0 then
shortname = ''
shortname = ''
break -- Several shortnames in the local language
break -- Several shortnames in the local language
end
end
shortname = s.mainsnak.datavalue.value.text
shortname = s.mainsnak.datavalue.value.text
end
end
end
end
if #shortname > 0 then
if #shortname > 0 then
propertyValue.label = langObject:ucfirst(hyphenate(shortname, lang))
propertyValue.label = langObject:ucfirst(hyphenate(shortname, lang))
end
end
end
end
-- Link row label (property name) to related article in content language:
-- Link row label (property name) to related article in content language:
local propertySubjects = propertyEntity:getBestStatements('P1629') -- 'P1629 = subject item of this property'
local propertySubjects = propertyEntity:getBestStatements('P1629') -- 'P1629 = subject item of this property'
if #propertySubjects == 1 and propertyEntity['claims']['P1629'][1].mainsnak.snaktype == 'value' then
if #propertySubjects == 1
and propertyEntity['claims']['P1629'][1].mainsnak.snaktype == 'value' then
local subjectItemQid = propertyEntity['claims']['P1629'][1].mainsnak.datavalue.value.id
local subjectItemQid = propertyEntity['claims']['P1629'][1].mainsnak.datavalue.value.id
articleSitelink = mw.wikibase.getSitelink(subjectItemQid)
articleSitelink = mw.wikibase.getSitelink(subjectItemQid)
if articleSitelink ~= nil then -- Property subject item has local article
if articleSitelink ~= nil then -- Property subject item has local article
propertyValue.label = '[[' .. articleSitelink .. '|' .. propertyValue.label .. ']]'
propertyValue.label = '[[' .. articleSitelink .. '|' .. propertyValue.label .. ']]'
end
end
end
end
end
end
local dataValues -- right table cell content
local dataValues -- right table cell content
if #statements == 1
if #statements == 1
and levels >= 2
and levels >= 2
and (properties_with_parents_hash[property]
and (properties_with_parents_hash[property]
or properties_with_children_hash[property])
or properties_with_children_hash[property])
then
then
dataValues = propertyValue.value
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.
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
propertyValue.label = '' -- Hide 'Followed by' in left column
end
end
if property == 'P155' or property == 'P156' then -- follows or followed by
if property == 'P155' or property == 'P156' then -- follows or followed by
dataValues = '• ' .. dataValues
dataValues = '• ' .. dataValues
end
end
local level = {}
local level = {}
-- Show parent/child item if any:
-- Show parent/child item if any:
if item['claims'][property][1].mainsnak.snaktype == 'value' then
if item['claims'][property][1].mainsnak.snaktype == 'value' then
level[1] = {}
level[1] = {}
level[1].value = item['claims'][property][1].mainsnak.datavalue.value -- (Can give non-best statement?)
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].item = mw.wikibase.getEntity(level[1].value.id) -- Time consuming
level[1].statements = mw.wikibase.getBestStatements(level[1].item.id, property)
level[1].statements = mw.wikibase.getBestStatements(level[1].item.id, property)
end
end
if item['claims'][property][1].mainsnak.snaktype == 'value' and #level[1].statements == 1 and level[1].statements[1].mainsnak.datavalue then
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
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
if level[1].qid ~= countryid then -- do not repeat country as administrative belonging or place
level[1].propertyValue = level[1].item:formatStatements(property)
level[1].propertyValue = level[1].item:formatStatements(property)
if level[1].propertyValue then
if level[1].propertyValue then
-- Show multi-level list as bulleted list:
-- Show multi-level list as bulleted list:
if not (property == 'P155' or property == 'P156') then
if not (property == 'P155' or property == 'P156') then
dataValues = '• ' .. dataValues
dataValues = '• ' .. dataValues
end
end
level[1].qid = level[1].statements[1].mainsnak.datavalue.value.id
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 properties_with_children_hash[property] then -- next lower level / child item: put in end of the list.
if property == 'P156' then -- follows
if property == 'P156' then -- follows
dataValues = dataValues
dataValues = dataValues
.. '<br/>• ' .. level[1].propertyValue.value
.. '<br/>• ' .. level[1].propertyValue.value
else -- indent
else -- indent
dataValues = dataValues
dataValues = dataValues
.. '<br/>' .. '&nbsp;• ' .. level[1].propertyValue.value
.. '<br/>' .. '&nbsp;• ' .. level[1].propertyValue.value
end
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/>&nbsp;' .. dataValues
end
end
local l = 2 -- level counter
while l<levels and level[l-1].item.claims[property][1].mainsnak.datavalue do
level[l]={}
level[l].value = level[l-1].item.claims[property][1].mainsnak.datavalue.value -- (Best statement?)
level[l].item = mw.wikibase.getEntity(level[l].value.id) -- Time consuming
level[l].statements = mw.wikibase.getBestStatements(level[l].item.id, property)
if #level[l].statements > 0 and level[l].statements[1].mainsnak.datavalue then
level[l].qid = level[l].statements[1].mainsnak.datavalue.value.id
if #level[l].statements == 1
and level[l].qid ~= countryid -- do not repeat country as administrative belonging or place
then
level[l].propertyValue = level[l].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[l].propertyValue.value
else -- indent
dataValues = dataValues .. '<br/>'
.. string.rep('&nbsp;', l) .. '• ' .. level[l].propertyValue.value
end
else -- next higher level / parent item
if property == 'P155' then -- followed by
dataValues = '• ' .. level[l].propertyValue.value
.. '<br/>' .. dataValues
else -- indent
dataValues = '• ' .. level[l].propertyValue.value
.. '<br/>&nbsp;' .. dataValues:gsub('<br/>', '<br/>&nbsp;')
end
end
l = l+1
else
break
end
else
break
end
end -- while l
if lang == 'sv' then
wikicategory = wikicategory .. '[[kategori:Databox med ' .. l .. ' nivåer]]'
end
end
if property == 'P155' then -- P155 (follows) was a bulleted list
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
else -- next higher level / parent item: put first in list
dataValues = dataValues
if property == 'P155' then -- followed by
.. "<p>\'\'\'" .. item:getLabel() .. "\'\'\'"
dataValues = '• ' .. level[1].propertyValue.value
if lang == 'da' or lang == 'sv' then
.. '<br/>' .. dataValues
propertyValue.label = 'Kronologi'
else -- indent
dataValues = '• ' .. level[1].propertyValue.value
merged_chronology = true
.. '<br/>&nbsp;' .. dataValues
end
end
if lang == 'en' then
end
propertyValue.label = 'Chronology'
merged_chronology = true
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('&nbsp;', 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/>&nbsp;' .. dataValues:gsub('<br/>', '<br/>&nbsp;')
end
end
lc = lc+1
else
break
end
else
break
end
end
end -- while lc
if lang == 'sv' then
wikicategory = wikicategory .. '[[Kategori:Databox med ' .. lc .. ' nivåer]]'
end
end
end
end
end
end
end
end
if property == 'P155' then -- P155 (follows) was a bulleted list
if level[1] then
else -- not a multi-level list
followed_by = mw.wikibase.getBestStatements(level[1].item.id, 'P156')
if datatype == 'url' then -- only show first url
if followed_by and #followed_by == 1 then -- P156 (followed by) may also be a bulleted list
if statements[1].mainsnak.snaktype == 'value' then
-- Show merged chronology list, including this wikidata object
if #statements[1].mainsnak.datavalue.value>40 then -- replace long url by "link"
dataValues = dataValues
if lang == 'sv' then
.. "<p>• \'\'\'" .. item:getLabel() .. "\'\'\'"
dataValues = frame:preprocess('[' .. statements[1].mainsnak.datavalue.value .. ' länk]')
else
if lang == 'da' or lang == 'sv' then
propertyValue.label = 'Kronologi'
dataValues = frame:preprocess('[' .. statements[1].mainsnak.datavalue.value .. ' link]')
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
end
else -- hide "https://" or "http:// and / in the end"
else -- hide "https://" or "http:// and / in the end"
dataValues = frame:preprocess('[' .. statements[1].mainsnak.datavalue.value
dataValues = frame:preprocess('[' .. statements[1].mainsnak.datavalue.value
.. ' ' .. statements[1].mainsnak.datavalue.value:gsub('https?://', ''):gsub('/$', '') .. ']')
.. ' ' .. statements[1].mainsnak.datavalue.value:gsub('https?://', ''):gsub('/$', '') .. ']')
end
end
end
end
elseif datatype == 'geo-shape' then -- only show first geo-shape
elseif datatype == 'geo-shape' then -- only show first geo-shape
if lang == 'sv' then
if lang == 'sv' then
dataValues = frame:preprocess('[https://commons.wikimedia.org/wiki/'
dataValues = frame:preprocess('[https://commons.wikimedia.org/wiki/'
.. statements[1].mainsnak.datavalue.value:gsub(' ', '_') .. ' kartlänk]')
.. statements[1].mainsnak.datavalue.value:gsub(' ', '_') .. ' kartlänk]')
else
else
dataValues = frame:preprocess('[https://commons.wikimedia.org/wiki/'
dataValues = frame:preprocess('[https://commons.wikimedia.org/wiki/'
.. statements[1].mainsnak.datavalue.value:gsub(' ', '_') .. ' link]')
.. statements[1].mainsnak.datavalue.value:gsub(' ', '_') .. ' link]')
end
end
elseif datatype == 'monolingualtext' then
elseif datatype == 'monolingualtext' then
for _, s in pairs(statements) do
for _, s in pairs(statements) do
if s.mainsnak.snaktype == 'value' and s.mainsnak.datavalue.value.language == lang then
if s.mainsnak.snaktype == 'value'
and s.mainsnak.datavalue.value.language == lang then
dataValues = frame:preprocess(s.mainsnak.datavalue.value)
dataValues = frame:preprocess(s.mainsnak.datavalue.value)
if lang == 'sv' then
if lang == 'sv' then
wikicategory = wikicategory .. '[[kategori:Databox med monolingualtext]]'
wikicategory = wikicategory .. '[[Kategori:Databox med monolingualtext]]'
end
end
break -- Maximum one monolingualtext per property
break -- Maximum one monolingualtext per property
end
end
end
end
else
else
dataValues = frame:preprocess(propertyValue.value)
dataValues = frame:preprocess(propertyValue.value)
if #statements > 1 then
if #statements > 1 then
dataValues = listSeparate(dataValues, list_separator)
dataValues = listSeparate(dataValues, list_separator)
end
end
if datatype == 'time' then
if datatype == 'time' then
dataValues = year(dataValues, lang, replaceTime)
dataValues = year(dataValues, lang, replaceTime)
end
end
if #statements >= math.max(list_length-3,3) and lang == 'sv' then --Warning on long but not hidden list
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]]'
wikicategory = wikicategory .. '[[Kategori:Databox med lång lista]]'
end
end
end
end
end
end
-- Replace "no value" with a dash:
-- Replace "no value" with a dash:
if dataValues and noValueDict[lang] then
if dataValues and noValueDict[lang] then
dataValues = dataValues:gsub('<span>' .. noValueDict[lang] .. '</span>', '<span>–</span>')
dataValues = dataValues:gsub('<span>' .. noValueDict[lang] .. '</span>', '<span>–</span>')
end
end
-- Render table row:
-- Render table row:
if dataValues and dataValues ~= '<span>–</span>' then
if dataValues and dataValues ~= '<span>–</span>' then
dataTable:tag('tr')
dataTable:tag('tr')
:tag('th')
:tag('th')
:css({
:css({
['vertical-align'] = 'text-top',
['vertical-align'] = 'text-top',
})
})
:attr('scope', 'row')
:attr('scope', 'row')
:attr('colspan', '1')
:attr('colspan', '1')
:wikitext( frame:preprocess( propertyValue.label)):done()
:wikitext(frame:preprocess(propertyValue.label)):done()
:tag('td')
:tag('td')
:css({
:css({
['vertical-align'] = 'text-top',
['vertical-align'] = 'text-top',
})
})
:attr('colspan', '2')
:attr('colspan', '2')
:wikitext(dataValues)
:wikitext(dataValues)
:wikitext('<sup class="noprint Inline-Template">&nbsp;[[File:Arbcom_ru_editing.svg|'
:wikitext('<sup class="noprint Inline-Template">&nbsp;[[File:Arbcom_ru_editing.svg|'
.. edit_message .. '|8px|baseline|class=noviewer|link=https://www.wikidata.org/wiki/'
.. edit_message .. '|8px|baseline|class=noviewer|link=https://www.wikidata.org/wiki/'
.. item.id .. '#' .. property .. ']]</sup>')
.. item.id .. '#' .. property .. ']]</sup>')
end -- if dataValues
end -- if dataValues
end -- if #statements
end -- if #statements
end -- if datatype
end -- if datatype
end -- for property
end -- for property
--Automatic coordinate location map(s)
--Automatic coordinate location map(s)
if zoom >= 0 then
if zoom >= 0 then
local coordinates_statements = item:getBestStatements('P625') -- P625 is coordinate location
local coordinates_statements = item:getBestStatements('P625') -- P625 is coordinate location
local cnt = 0
local cnt = 0
for _, s in pairs(coordinates_statements) do
for _, s in pairs(coordinates_statements) do
if s.mainsnak.datavalue and s.mainsnak.datavalue.value.globe == 'http://www.wikidata.org/entity/Q2' then
if s.mainsnak.datavalue and s.mainsnak.datavalue.value.globe == 'http://www.wikidata.org/entity/Q2' then
cnt = cnt + 1
cnt = cnt + 1
databoxRoot:wikitext(buildInteractiveMap(width, s.mainsnak.datavalue.value, item.id, zoom))
databoxRoot:wikitext(buildInteractiveMap(width, s.mainsnak.datavalue.value, item.id, zoom))
if lang == 'sv' then
if lang == 'sv' then
if cnt == 1 then
if cnt == 1 then
wikicategory = wikicategory .. '[[Kategori:Sidor med kartor skapade med Databox]]' .. ' '
wikicategory = wikicategory .. '[[Kategori:Sidor med kartor skapade med Databox]]' .. ' '
Linje 865: Linje 901:
wikicategory = wikicategory .. '[[Kategori:Sidor med flera kartor skapade med Databox]]' .. ' '
wikicategory = wikicategory .. '[[Kategori:Sidor med flera kartor skapade med Databox]]' .. ' '
end
end
end
end
end
end
if cnt >= maxFiles then
if cnt >= maxFiles then
break -- Show maximum maxFiles maps or coordinates.
break -- Show maximum maxFiles maps or coordinates.
end
end
end -- for
end -- for
end
end


--Other commonsMedia files: show first good file for each property that have media legend in content language
--Other commonsMedia files: show first good file for each property that have media legend in content language
if tonumber(height) > 0 then
if tonumber(height) > 0 then
for _, property in pairs(properties) do
for _, property in pairs(properties) do
local datatype = item.claims[property][1].mainsnak.datatype
local datatype = item.claims[property][1].mainsnak.datatype
local statements = item:getBestStatements(property)
local statements = item:getBestStatements(property)
if (datatype == 'commonsMedia')
if (datatype == 'commonsMedia')
and not property_blacklist_hash[property]
and not property_blacklist_hash[property]
and property ~= 'P18' then -- Image showed separately
and property ~= 'P18' then -- Image showed separately
local files = item:getBestStatements(property)
local files = item:getBestStatements(property)
if #files >= 1 then
if #files >= 1 then
local file
local file
Linje 891: Linje 927:
for _, q in pairs(i.qualifiers.P2096) do
for _, q in pairs(i.qualifiers.P2096) do
if q.snaktype == 'value' and q.datavalue.value.language == lang then
if q.snaktype == 'value' and q.datavalue.value.language == lang then
caption = q
caption = q
file = i
file = i
break
break
Linje 913: Linje 949:
if file then
if file then
if caption then
if caption then
databoxRoot
databoxRoot
:tag('div')
:tag('div')
:css({
:css({
['text-align'] = 'center',
['text-align'] = 'center',
padding = '0.0em 0.4',
padding = '0.0em 0.4',
})
})
:wikitext('[[File:' .. file.mainsnak.datavalue.value .. '|frameless|'
:wikitext('[[File:' .. file.mainsnak.datavalue.value .. '|frameless|'
.. width .. 'x' .. height .. 'px]]')
.. width .. 'x' .. height .. 'px]]')
databoxRoot
databoxRoot
:tag('div')
:tag('div')
:css({
:css({
['text-align'] = 'center',
['text-align'] = 'center',
['font-size'] = '90%',
['font-size'] = '90%',
['line-height'] = '140%',
['line-height'] = '140%',
['padding-bottom'] = '0.5em',
['padding-bottom'] = '0.5em',
})
})
:wikitext(caption.datavalue.value.text)
:wikitext(caption.datavalue.value.text)
:wikitext('<sup class="noprint Inline-Template">&nbsp;[[File:Arbcom_ru_editing.svg|'
:wikitext('<sup class="noprint Inline-Template">&nbsp;[[File:Arbcom_ru_editing.svg|'
.. edit_message .. '|8px|baseline|class=noviewer|link=https://www.wikidata.org/wiki/'
.. edit_message .. '|8px|baseline|class=noviewer|link=https://www.wikidata.org/wiki/'
.. item.id .. '#' .. property .. ']]</sup>')
.. item.id .. '#' .. property .. ']]</sup>')
else -- no caption
else -- no caption
databoxRoot
databoxRoot
:tag('div')
:tag('div')
:css({
:css({
['text-align'] = 'center',
['text-align'] = 'center',
padding = '0.0em 0.4',
padding = '0.0em 0.4',
})
})
:wikitext('[[File:' .. file.mainsnak.datavalue.value .. '|frameless|'
:wikitext('[[File:' .. file.mainsnak.datavalue.value .. '|frameless|'
.. width .. 'x' .. height .. 'px]]')
.. width .. 'x' .. height .. 'px]]')
databoxRoot
databoxRoot
:tag('div')
:tag('div')
:css({
:css({
['text-align'] = 'center',
['text-align'] = 'center',
['font-size'] = '90%',
['font-size'] = '90%',
['line-height'] = '140%',
['line-height'] = '140%',
['padding-bottom'] = '0.5em',
['padding-bottom'] = '0.5em',
})
})


end -- if caption
end -- if caption
if lang == 'sv' then
if lang == 'sv' then
if property == 'P242' then -- P242 is 'locator map image'
if property == 'P242' then -- P242 is 'locator map image'
wikicategory = wikicategory .. '[[Kategori:Sidor med översiktskartor skapade med Databox]]' .. ' '
wikicategory = wikicategory .. '[[Kategori:Sidor med översiktskartor skapade med Databox]]' .. ' '
else
else
wikicategory = wikicategory .. '[[Kategori:Sidor med andra mediafiler i Databox]]' .. ' '
wikicategory = wikicategory .. '[[Kategori:Sidor med andra mediafiler i Databox]]' .. ' '
end
end
end
end
end -- if file
end -- if file
end -- if #files
end -- if #files
end -- if datatype
end -- if datatype
end -- for _, property
end -- for _, property
end -- if height
end -- if height


--Category
--Category
if mw.title.getCurrentTitle().namespace == 0 then -- Only in main namespace
if mw.title.getCurrentTitle().namespace == 0 then -- Only in main namespace
if tostring(databoxRoot):match('<span>Q%d+</span>') then
if tostring(databoxRoot):match('<span>Q%d+</span>') then
if lang == 'da' then
if lang == 'da' then
wikicategory = wikicategory .. '[[Kategori:Databox der viser Qid-kode]]' .. ' '
wikicategory = wikicategory .. '[[Kategori:Databox der viser Qid-kode]]' .. ' '
elseif lang == 'sv' then
elseif lang == 'sv' then
wikicategory = wikicategory .. '[[Kategori:Databox som visar qid-kod]]' .. ' '
wikicategory = wikicategory .. '[[Kategori:Databox som visar qid-kod]]' .. ' '
elseif lang == 'en' then
elseif lang == 'en' then
wikicategory = wikicategory .. '[[Category:Databox that shows qid code]]' .. ' '
wikicategory = wikicategory .. '[[Category:Databox that shows qid code]]' .. ' '
elseif lang == 'frr' then
wikicategory = wikicategory .. '[[Kategorie:Databox mit Qid-Code]]' .. ' '
end
end
end
end
if #wikicategory then
if #wikicategory then
databoxRoot:wikitext(wikicategory)
databoxRoot:wikitext(wikicategory)
end
if #dump then
databoxRoot:wikitext(dump)
end
end
end
end
if #dump then
databoxRoot:wikitext(dump)
end
return tostring(databoxRoot)
return tostring(databoxRoot)
end -- function
end -- function

Nuværende version fra 3. mar. 2024, 03:02

-- 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äöæøáéíóúýàèâêëüãŭœāēīōūəąęóадеёзоу])",
				"&shy;%1") -- Insert soft-hyphens before each consonant that is followed by vowel
			:gsub("&shy;([\128-\193])", "%1" ) -- Revert split of two-byte UTF-8 character
			:gsub("-(%a?%a?%a?%a?)&shy;", "-%1"):gsub("&shy;(%a?%a?%a?%a?)-", "%1-") -- Not too near a hard hyphen
			
			-- Some Scandinavian exceptions for wikidata properties, relevant to similar languages:
			:gsub("&shy;x", "x&shy;") -- Example: tids-komp-le-xi-tet -> tids-komp-lex-i-tet   
			:gsub("sc&shy;h", "&shy;sch") -- Example: sc-h -> -sch
			:gsub("ss&shy;j", "s&shy;sj")-- Example: ss-j-> s-sj
			:gsub("n&shy;g", "ng&shy;") -- Example: n-g -> ng- 
			:gsub("ngs", "ngs&shy;") -- Example: Befolk-ningsg-rup-pe -> Befolk-nings-g-rup-pe, Rege-ring-s-che-fens -> Rege-rings-chefens 
			:gsub("g&shy;rup&shy;pe", "&shy;gruppe") -- Example: g-rup-pe -> -gruppe
			:gsub("nist&shy;ra", "nis&shy;tra") -- Example: admi-nist-ra-tion -> admi-nis-tra-tion
			:gsub("&shy;ror&shy;ga[&shy;]*n", "r&shy;organ") -- Example: dotte-ror-ga-ni-sa-tion -> dotter-organi-sa-tion
			:gsub("&shy;rob[&shy;]*jek", "r&shy;objek") -- Example: dot-te-rob-jekt -> dot-ter-objekt
			:gsub("s&shy;ta&shy;tus", "&shy;status") -- Example: skydds-status
			:gsub("k&shy;las[&shy;]*s", "&shy;klass") -- Example: deci-malk-las-si-fi-ka-tion -> deci-mal-klas-si-fi-ka-tion
			:gsub("&shy;nom&shy;rå&shy;de", "n&shy;område") -- Example: vatte-nom-rå-de -> vatten-område
			:gsub("&shy;som&shy;rå&shy;de", "s&shy;område") -- Example: Rets-gyl-dig-hed-som-rå-de -> Rets-gyl-dig-heds-om-rå-de
			:gsub("ra&shy;lort", "ral&shy;ort") -- Example: central-ort
			:gsub("s&shy;kydd", "&shy;skydd") -- Example: Kul-turs-kydd -> Kul-tur-skydd
			:gsub("k&shy;ri&shy;te&shy;ri", "&shy;kri&shy;te&shy;ri")-- Example: Värld-sarvsk-ri-te-rium -> Värld-sarvs-kri-te-rium
			:gsub("guasp&shy;he", "gua&shy;sphe") -- Example: lingua-sphere
			:gsub("gars&shy;kap", "gar&shy;skap") -- Example: medbor-gars-kap -> medbor-gar-skap
			:gsub("k&shy;var&shy;ter", "&shy;kvarter") -- Example: Hovedk-var-ter -> Hoved-kvarter
			:gsub("s&shy;ted", "&shy;sted") -- Example: Pro-duk-tionss-ted -> Pro-duk-tions-sted
			:gsub("&shy;&shy;", "&shy;") -- Example -- -> -
		end
	end
	return result:sub(2,-1)
	-- :gsub("&shy;", "-") -- 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">&nbsp;[[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">&nbsp;[[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">&nbsp;[[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/>' .. '&nbsp;• ' .. 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/>&nbsp;' .. 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('&nbsp;', 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/>&nbsp;' .. dataValues:gsub('<br/>', '<br/>&nbsp;')
												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">&nbsp;[[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">&nbsp;[[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