Module:Databox/test
ظٲہِریَتھ
"یَمہٕ ماڈیوٗلُک دَستاویز ییٚہِ Module:Databox/test/دَستاویز جاے بَناونہٕ"
-- Please DO NOT edit this page unless you know what you are doing.
-- Maintainer: User:511KeV
-- https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual
-- https://www.mediawiki.org/wiki/Extension:Wikibase_Client/Lua
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
'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
'P6186', -- category for eponymous categories
'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
'P8596', -- category for the exterior of the item
'P301', -- category's main topic
'P971', -- category combines topics
'P3876', -- category for alumni of educational institution
'P8933', -- category for the view from the item
'P1753', -- list related to category
'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
'P2559', -- Wikidata usage instructions
'P1343', -- described by source
'P972', -- catalogue
'P1282', -- OSM tag or key
'P4839', -- Wolfram Language entity code
'P6104', -- Maintained by Wikiproject
'P5996', -- Category for films in this language
'P735', -- Given name
'P734', -- Family name
'P1559', -- Native name (Handled separately)
'P21', -- Sex or gender
'P2184', -- history of topic
'P1438', -- Jewish Encyclopedia ID
'P7867', -- category for maps
'P8402', -- Open Data portal
'P1448', -- official name (Handled separately)
'P569', -- date of birth (Handled separately)
'P570', -- date of death (Handled separately)
'P19', -- place of birth
'P20', -- place of death
'P27', -- country of citizenship
'P2747', -- Filmiroda rating
'P7561', -- category for the interior of the item
'P1196', -- manner of death
'P6365', -- member category
'P465', -- sRGB color hex triplet
'P487', -- Unicode character
'P7084', -- related category
'P7763', -- Copyright status as a creator
'P1814', -- name in kana
'P2001', -- Revised Romanization
'P2572', -- Hashtag
'P8989', -- category for the view of the item
'P6363', -- WordLift
}
-- Exceptions to the datatype blocking:
local property_whitelist = {
'P856', -- official website
'P3896',-- geoshape
'P345', -- IMDB id
'P6375' -- street address
}
-- Properties with higher level items (Bulleted Hierarchy):
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
}
-- Merge two tables and return a new table
function mergeTables(first, second)
result = {}
for k,v in pairs(first) do
table.insert(result, v)
end
for k,v in pairs(second) do
table.insert(result, v)
end
return result
end
-- Turn index based tables into key based tables
function valuesToKeys(array)
local result = {}
for _, v in pairs(array) do
result[v:upper()] = true
end
return result
end
function getBirthStatement(lang, date_of_birth, date_of_death, place_of_birth)
local birth_time = ''
if date_of_death then
birth_time = formatDate(lang, date_of_birth.time)
else
local date_of_birth_parts = mw.text.split(formatDate(lang, date_of_birth.time, nil, 'Y-m-j'), '-')
birth_time = string.format('{{Birth date and age|%s|%s|%s}}',
date_of_birth_parts[1], date_of_birth_parts[2], date_of_birth_parts[3])
end
local birth = birth_time
if place_of_birth then
-- Try to get the Kashmiri article name for the entity
local birth_location = mw.wikibase.getSitelink(place_of_birth.id, 'kswiki')
local link = true
if not birth_location then
-- If there was no Kashmiri article for the entity, then get an article name from other wikis
birth_location = mw.wikibase.getLabel(place_of_birth.id)
link = false
end
if birth_location then
if link then birth_location = '[[' .. birth_location .. ']]' end
birth = birth .. '<br>' .. birth_location
local birth_country = getBestStatementById(place_of_birth.id, 'P17')
if birth_country then
local birth_country_label = mw.wikibase.getSitelink(birth_country.id, 'kswiki')
local link = true
if not birth_country_label then
birth_country_label = mw.wikibase.getSitelink(birth_country.id, 'enwiki')
link = false
end
if link then birth_country_label = '[[' .. birth_country_label .. ']]' end
birth = birth .. '، ' .. birth_country_label
end
end
end
return birth
end
function getDeathStatement(lang, date_of_birth, date_of_death, place_of_death)
local date_of_birth_parts = mw.text.split(formatDate(lang, date_of_birth.time, nil, 'Y-m-j'), '-')
local date_of_death_parts = mw.text.split(formatDate(lang, date_of_death.time, nil, 'Y-m-j'), '-')
local death_time = string.format('{{Death date and age|%s|%s|%s|%s|%s|%s}}',
date_of_death_parts[1], date_of_death_parts[2], date_of_death_parts[3],
date_of_birth_parts[1], date_of_birth_parts[2], date_of_birth_parts[3])
local death = death_time
if place_of_death then
local death_location = mw.wikibase.getSitelink(place_of_death.id, 'kswiki')
local link = true
if not death_location then
death_location = mw.wikibase.getSitelink(place_of_death.id, 'enwiki')
link = false
end
if not death_location then
death_location = mw.wikibase.getLabel(place_of_death.id)
link = false
end
if death_location then
if link then death_location = '[[' .. death_location .. ']]' end
death = death .. '<br>' .. death_location
local death_country = getBestStatementById(place_of_death.id, 'P17')
if death_country then
local death_country_label = mw.wikibase.getSitelink(death_country.id, 'kswiki')
local link = true
if not death_country_label then
death_country_label = mw.wikibase.getSitelink(death_country.id, 'enwiki')
link = false
end
if link then death_country_label = '[[' .. death_country_label .. ']]' end
death = death .. '، ' .. death_country_label
end
end
end
return death
end
-- Convert Arabic numbers (0123456789) to Kashmiri numbers (٠١٢٣٤٥٦٧٨٩)
function toKashmirinumbers(text)
return text:gsub('0', '0')
:gsub('1', '1')
:gsub('2', '2')
:gsub('3', '3')
:gsub('4', '4')
:gsub('5', '5')
:gsub('6', '6')
:gsub('7', '7')
:gsub('8', '8')
:gsub('9', '9')
:gsub('square kilometre', 'کِلومیٖٹَر چَکور')
:gsub('kilometre', 'کِلومیٖٹَر')
end
function formatDate(lang, dateString, fallback, format)
if not format then format = 'j xg Y' end
if dateString:sub(1, 1) == '-' then return fallback or dateString end
dateString = dateString:gsub('%-00%-00T', '-01-01T')
return lang:formatDate(format, dateString, false)
end
function isEnglish(text)
return string.find(text, '[abcdefghijklmnopqrstuvwxyz]') ~= nil
end
-- Returns the best statements for the first property this item has
function getBestStatement(item, ...)
for i,v in ipairs(arg) do
local statements = item:getBestStatements(v)
if len(statements) >= 1 and statements[1] and statements[1].mainsnak.datavalue then
return statements[1].mainsnak.datavalue.value
end
end
return nil
end
-- Returns the best statements for the first property this item has
function getBestStatementById(id, ...)
for i,v in ipairs(arg) do
local statements = mw.wikibase.getBestStatements( id, v)
if len(statements) >= 1 and statements[1] and statements[1].mainsnak.datavalue then
return statements[1].mainsnak.datavalue.value
end
end
return nil
end
function len(t)
local count = 0
for _ in pairs(t) do count = count + 1 end
return count
end
function isEmpty(s)
return s == nil or s == ''
end
local module_properties = { ['item'] = true, ['بەند'] = true, ['کھٕتِتھ'] = true, ['تەنیا کوردی'] = true }
function getOverridenProperties(args)
properties = {}
for key, value in pairs(args) do
if (not module_properties[key]) then
properties[key:upper()] = value
end
end
return properties
end
local p = {}
function p.databox(frame)
local args = frame:getParent().args
local itemId = nil
local show_english_properties = true
if args.item or args['بەند'] then
itemId = args.item or args['بەند']
end
if args['تەنیا کوردی'] == true or args['تەنیا کوردی'] == 'بەڵێ' then
show_english_properties = false
end
local overriden_properties = getOverridenProperties(args)
local hidden_properties = {}
if args['کھٕتِتھ'] then
hidden_properties = mw.text.split(args['کھٕتِتھ'], "%s*[,،]%s*")
end
local lang = mw.language.getContentLanguage()
local item = mw.wikibase.getEntity(itemId)
local levels = 3 -- Default Max Levels for hierarchy
if item == nil then
mw.addWarning("Wikidata item not found")
return ""
end
--Table Construction
local dataTable = mw.html.create('table')
:addClass('infobox vcard')
:css({
['width'] = '22em'
})
-- Title
dataTable:tag('tr'):tag('th')
:addClass('fn')
:attr('colspan', 2)
:css({
['text-align'] = 'center',
['background-color'] = args.bgcolor or '#F2F2F2',
['padding'] = '0.5em 0',
['margin'] = '0.5em 0',
['font-size'] = '125%',
['color'] = args.titletextcolor or 'black',
['font-weight'] = 'bold',
})
:wikitext(item:getLabel() or mw.title.getCurrentTitle().text)
-- Native name
local officialName = getBestStatement(item, 'P1448', 'P1559')
if officialName then
if officialName.language ~= 'ks' then
local langName = mw.language.fetchLanguageName(officialName.language, 'ks')
dataTable:tag('tr'):tag('th')
:attr('colspan', 2)
:css({
['text-align'] = 'center',
padding = '0.5em 0',
margin = '0.5em 0',
['font-size'] = '90%',
['font-weight'] = 'bold',
['max-width'] = '240px'
})
:wikitext('اَصٕل ناو [[' .. langName ..']] زَبانہِ مَنٛز: ' .. officialName.text)
end
end
-- Image
local image = args['تَصویٖر'] or args['image']
if image == nil then
local images = item:getBestStatements('P18')
if #images >= 1 then
image = images[1].mainsnak.datavalue.value
end
end
if image ~= nil then
dataTable:tag('tr'):tag('td')
:attr('colspan', 2)
:css({ ['text-align'] = 'center'})
:wikitext('[[File:' .. image .. '|frameless|250px]]')
end
-- P31 (Instance of)
local p31_stmts = item:getBestStatements('P31')
local p31_links = {} -- ALWAYS create this table, even if empty
if #p31_stmts > 0 then
for i = 1, math.min(#p31_stmts, 2) do
local snak = p31_stmts[i].mainsnak
if snak.datavalue and snak.datavalue.value.id then
local id = snak.datavalue.value.id
local label = mw.wikibase.getLabel(id) or id
local sitelink = mw.wikibase.getSitelink(id)
if sitelink then
table.insert(p31_links, '[[' .. sitelink .. '|' .. label .. ']]')
else
table.insert(p31_links, label)
end
end
end
end
-- Render P31 row only if we actually have links
if #p31_links > 0 then
dataTable:tag('tr'):tag('td')
:attr('colspan', 2)
:css({
['background-color'] = args.bgcolor or '#F2F2F2',
['font-weight'] = 'bold',
['text-align'] = 'center',
['color'] = args.titletextcolor or 'black',
['padding'] = '0.2em'
})
:wikitext(table.concat(p31_links, '، '))
end
local properties = mw.wikibase.orderProperties(item:getProperties())
local property_blacklist_hash = valuesToKeys(mergeTables(property_blacklist, hidden_properties))
local property_whitelist_hash = valuesToKeys(property_whitelist)
local properties_with_parents_hash = valuesToKeys(properties_with_parents)
local properties_with_children_hash = valuesToKeys(properties_with_children)
property_blacklist_hash['P31'] = true
property_blacklist_hash['P18'] = true
local edit_message = mw.message.new('vector-view-edit'):plain()
-- Birth/Death Logic
local date_of_birth = getBestStatement(item, 'P569')
local date_of_death = getBestStatement(item, 'P570')
local instance_of = getBestStatement(item, 'P31')
local place_of_birth = getBestStatement(item, 'P19')
local place_of_death = getBestStatement(item, 'P20')
local countryid = ' '
pcall(function ()
countryid = item.claims['P17'][1].mainsnak.datavalue.value.id
end)
if instance_of and instance_of.id == 'Q5' and date_of_birth and date_of_birth.time:sub(1, 1) ~= '-' then
local birth = getBirthStatement(lang, date_of_birth, date_of_death, place_of_birth)
dataTable:tag('tr')
:tag('th')
:attr('scope', 'row')
:css({
['padding-top'] = '0.225em',
['line-height'] = '1.1em',
['padding-right'] = '0.65em'
})
:wikitext('پٲدٲیِش'):done()
:tag('td')
:css({ ['line-height'] = '1.4em', ['max-width'] = '180px' })
:wikitext(frame:preprocess(birth))
if date_of_death then
local death = getDeathStatement(lang, date_of_birth, date_of_death, place_of_death)
dataTable:tag('tr')
:tag('th')
:attr('scope', 'row')
:css({
['padding-top'] = '0.225em',
['line-height'] = '1.1em',
['padding-right'] = '0.65em'
})
:wikitext('وَفات'):done()
:tag('td')
:css({ ['line-height'] = '1.4em', ['max-width'] = '180px' })
:wikitext(frame:preprocess(death))
end
end
local merged_chronology = false -- flag for P155/P156
for _, property in pairs(properties) do
-- Skip rendering P156 separately if we merged it in P155 loop
local skip_this_property = false
if merged_chronology and property == 'P156' then
skip_this_property = true
end
if not skip_this_property then
-- Safely get datatype
local claims = item.claims[property]
local datatype = 'unknown'
if claims and claims[1] and claims[1].mainsnak and claims[1].mainsnak.datatype then
datatype = claims[1].mainsnak.datatype
end
local english_label = mw.wikibase.getLabelByLang(property, 'en')
english_label = english_label and english_label:upper() or property
local kashmiri_label = mw.wikibase.getLabelByLang(property, 'ks')
if property == 'P1082' or property == 'P1120' or property == 'P1339' or property == 'P2046' or property == 'P2044' then
datatype = 'number'
end
overriden_value = overriden_properties[english_label] or overriden_properties[kurdish_label]
local shouldShow = false
if property_whitelist_hash[property] then
shouldShow = true
elseif datatype ~= 'commonsMedia' and datatype ~= 'external-id' and
datatype ~= 'quantity' and datatype ~= 'wikibase-property' and
datatype ~= 'geo-shape' and datatype ~= 'tabular-data' and
(not property_blacklist_hash[property] and not property_blacklist_hash[english_label] and not property_blacklist_hash[kurdish_label]) then
shouldShow = true
end
local statements = item:getBestStatements(property)
if shouldShow and (show_english_properties or kurdish_label ~= nil or overriden_value) and #statements <= 30 then
local propertyValue = item:formatStatements(property)
local value = overriden_value
-- Check if value is manually overriden
if (value == nil) then
-- HIERARCHY FEATURE LOGIC
if #statements == 1 and levels >= 2 and (properties_with_parents_hash[property] or properties_with_children_hash[property]) then
value = propertyValue.value
if property == 'P155' or property == 'P156' then -- follows or followed by
value = '• ' .. value
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
level[1].item = mw.wikibase.getEntity(level[1].value.id)
if level[1].item then
level[1].statements = mw.wikibase.getBestStatements(level[1].item.id, property)
else
level[1].statements = {}
end
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
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
value = '• ' .. value
end
if properties_with_children_hash[property] then -- next lower level / child item
if property == 'P156' then
value = value .. '<br/>• ' .. level[1].propertyValue.value
else
value = value .. '<br/>' .. ' • ' .. level[1].propertyValue.value
end
else -- next higher level / parent item
if property == 'P155' then
value = '• ' .. level[1].propertyValue.value .. '<br/>' .. value
else
value = '• ' .. level[1].propertyValue.value .. '<br/> ' .. value
end
end
local lc = 2 -- level counter
while lc < levels and level[lc-1].item and level[lc-1].item.claims[property] and level[lc-1].item.claims[property][1] 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
level[lc].item = mw.wikibase.getEntity(level[lc].value.id)
if not level[lc].item then break end
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 then
level[lc].propertyValue = level[lc].item:formatStatements(property)
if properties_with_children_hash[property] then
if property == 'P156' then
value = value .. '<br/>' .. '• ' .. level[lc].propertyValue.value
else
value = value .. '<br/>' .. string.rep(' ', lc) .. '• ' .. level[lc].propertyValue.value
end
else
if property == 'P155' then
value = '• ' .. level[lc].propertyValue.value .. '<br/>' .. value
else
value = '• ' .. level[lc].propertyValue.value .. '<br/> ' .. value:gsub('<br/>', '<br/> ')
end
end
lc = lc+1
else
break
end
else
break
end
end -- while lc
end
end
end
if property == 'P155' then -- P155 (follows)
if level[1] and level[1].item then
followed_by = mw.wikibase.getBestStatements(level[1].item.id, 'P156')
if followed_by and #followed_by == 1 then
-- Show merged chronology list
value = value .. "<p>• \'\'\'" .. item:getLabel() .. "\'\'\'"
propertyValue.label = 'تَوٲریٖخ' -- Chronology in Kashmiri (approx)
merged_chronology = true
end
end
end
-- END HIERARCHY LOGIC
else
-- Standard processing for non-hierarchical items
if datatype == 'time' then
local statementObject = getBestStatement(item, property)
if statementObject and statementObject.time then
local dateString = statementObject.time
if property == 'P1317' or property == 'P2031' then
value = formatDate(lang, dateString, propertyValue.value, 'Y')
else
value = formatDate(lang, dateString, propertyValue.value)
end
else
value = ''
end
else
value = propertyValue.value
end
end
elseif (value:find("^[Q]%d+") ~= nil) then
value = '[[' .. mw.wikibase.getSitelink(value) .. ']]'
end
if (datatype == 'time' or datatype == 'number') then
value = toKashmirinumbers(value)
end
if not isEmpty(value) then
dataTable:tag('tr')
:tag('th')
:attr('scope', 'row')
:css({
['padding-top'] = '0.225em',
['line-height'] = '1.1em',
['padding-right'] = '0.65em',
['vertical-align'] = 'text-top'
})
:wikitext(lang:ucfirst(propertyValue.label)):done()
:tag('td')
:css({
['line-height'] = '1.4em',
['max-width'] = '180px',
['vertical-align'] = 'text-top'
})
:wikitext(frame:preprocess(value))
end
end
end -- end skip_this_property check
end
-- MANUAL ROWS
for i = 1, 5 do
local label_param = 'label' .. i
local data_param = 'data' .. i
local label_value = args[label_param]
local data_value = args[data_param]
if label_value and data_value and #label_value > 0 and #data_value > 0 then
dataTable:tag('tr')
:tag('th')
:attr('scope', 'row')
:css({
['padding-top'] = '0.225em',
['line-height'] = '1.1em',
['padding-right'] = '0.65em'
})
:wikitext(label_value)
:done()
:tag('td')
:css({
['line-height'] = '1.4em',
['max-width'] = '180px'
})
:wikitext(frame:preprocess(data_value))
:done()
:done()
end
end
-- Map
local coordinates_statements = item:getBestStatements('P625')
if #coordinates_statements == 1 and coordinates_statements[1].mainsnak.datavalue and coordinates_statements[1].mainsnak.datavalue.value.globe == 'http://www.wikidata.org/entity/Q2' then
local latitude = coordinates_statements[1].mainsnak.datavalue.value.latitude
local longitude = coordinates_statements[1].mainsnak.datavalue.value.longitude
local geojson = {
type = 'Feature',
geometry = {
type = 'Point',
coordinates = { longitude, latitude }
},
properties = {
title = item:getLabel() or mw.title.getCurrentTitle().text,
['marker-symbol'] = 'marker',
['marker-color'] = '#224422',
}
}
dataTable:tag('tr'):tag('td')
:attr('colspan', 2)
:css({ ['text-align'] = 'center'})
:wikitext(frame:extensionTag('mapframe', mw.text.jsonEncode(geojson), {
height = 250,
width = 250,
frameless = 'frameless',
align = 'center',
latitude = latitude,
longitude = longitude,
zoom = 6
}))
end
local div_start = '<div style="border-style: solid; border-color:gray; border-width: 1px 0 0 0; margin-top: 2em; text-align: center;">'
local pen_icon = ' [[File:Wikidata-logo.svg|' .. edit_message .. '|22px|baseline|class=noviewer|link=https://www.wikidata.org/wiki/' .. item.id .. ']]'
local edit_message_link = '[https://www.wikidata.org/wiki/' .. item.id .. ' وِکی ڈیٹا پؠٹھ کٔرِو اؠڈِٹ]'
dataTable:tag('tr'):tag('td')
:attr('colspan', 2)
:css({ ['text-align'] = 'center'})
:wikitext(div_start .. edit_message_link .. pen_icon .. '</div>')
return tostring(dataTable)
end
return p