יחידה:LocationAndCountry
יחידה זו מבוססת על ro:Modul:LocationAndCountry להצגה של מיקום בצורה היררכית ומבוססת זמן:
- בצורה היררכית - מציגה את המקום בצירוף היחידה האדמיניסטרטיבית או המדינה
- מבוססת זמן - כאשר מיקום היה שייך בעבר למדינה אחת, ובהמשך אותה מדינה התפרקה או שהמקום עבר לידי מדינה אחרת - היחידה יודעת להיעזר בתאריך התחלה (P580) ותאריך סיום (P582) על מנת לחלץ את המדינה הנכונה ביחס לתאריך מסוים
--[[Adapted from ro:Modul:LocationAndCountry with changes:
* Using PropertyLink for linking format
* No use of external modules that exist in rowiki but have different version in hewiki such as wikidata and date modules
* findLinkToItem/findDateValues/findClaimForTimestamp is local instead of wikidata module
* disabled capabilities:
* outputReferences
* offical/short name
]]
-- will display a wikidata property representing a location, followed by a comma and the name of the country, both with wikilinks
-- the first argument specifies the parameter to be displayed
-- the second argument specifies the entity ID
-- the third argument specifies a timestamp showing the moment in time for which the country is to be identified
-- the fourth argument specifies the maximum number of values to be processed (default 1)
-- the fifth argument specifies the separator to use when displaying multiple values
local getArgs = require('Module:Arguments').getArgs
local HeDateUtils = require('Module:תאריך')
local TableTools = require('Module:TableTools')
local PropertyLink = require('Module:PropertyLink')
local Parenthesis = require('Module:סוגריים')
local p = {}
function emptyToNil(args)
local str = args[1]
if str == '' then return nil end
return str
end
local function isValueSnak(snak)
return snak and snak.snaktype == 'value'
end
local function hasValueSnak(claim)
return claim and claim.type == 'statement' and isValueSnak(claim.mainsnak)
end
local function findDateValues(propertyId, entityId)
entityId = entityId or mw.wikibase.getEntityIdForCurrentPage()
if entityId then
local bestclaims = mw.wikibase.getBestStatements(entityId, propertyId)
local bestdates = {}
if bestclaims then for k, v in pairs(bestclaims) do
if hasValueSnak(v) and v.mainsnak.datatype == 'time' then
local d = HeDateUtils.newFromWikidataValue(v.mainsnak.datavalue.value)
d.claim = v
table.insert(bestdates, d)
elseif hasValueSnak(v) then
local d = {}
d.claim = v
table.insert(bestdates, d)
end
end end
return bestdates
end
end
local timestampComparator = function(p1, p2)
if p1 and p2 then
local q1 = p1.qualifiers
local q2 = p2.qualifiers
local d1 = nil
local d2 = nil
if q1 and q2 then
if q1['P580'] and q1['P580'][1] and q1['P580'][1].datavalue then
d1 = HeDateUtils.newFromWikidataValue(q1['P580'][1].datavalue.value)
end
if q2['P580'] and q2['P580'][1] and q2['P580'][1].datavalue then
d2 = HeDateUtils.newFromWikidataValue(q2['P580'][1].datavalue.value)
end
if d1 and d2 then return not HeDateUtils.le(d2, d1, true)
elseif d1 then return true
elseif d2 then return false end
elseif q1 then return true
elseif q2 then return false
end
else
if p1 then return true end
if p2 then return false end
end
return false
end
local function findSortedClaimsForProperty(entity, propertyId)
if entity == nil then entity = mw.wikibase.getEntityIdForCurrentPage() end
local rawClaims = mw.wikibase.getAllStatements(entity, propertyId)
if rawClaims == nil then return {} end
table.sort(rawClaims, timestampComparator)
return rawClaims
end
local function findClaimForTimestamp(entityId, propertyId, timestamp)
local propClaims = findSortedClaimsForProperty(entityId, propertyId)
local bestClaims = {}
local bestNoTimeClaim
if propClaims then for _,eachPropClaim in ipairs(propClaims) do
if hasValueSnak(eachPropClaim)
and mw.wikibase.entity.claimRanks['RANK_' .. mw.ustring.upper(eachPropClaim.rank)] >= mw.wikibase.entity.claimRanks.RANK_NORMAL then
if eachPropClaim.mainsnak.datavalue.type ~= 'monolingualtext' or eachPropClaim.mainsnak.datavalue.value.language == 'he' then
local before = nil
local after = nil
if eachPropClaim.qualifiers then
if eachPropClaim.qualifiers['P580'] and eachPropClaim.qualifiers['P580'][1] and isValueSnak(eachPropClaim.qualifiers['P580'][1]) then
before = HeDateUtils.julianToGregorian(HeDateUtils.newFromWikidataValue(eachPropClaim.qualifiers['P580'][1].datavalue.value))
--after = GregorianDate.convertToGregorianIfInInterval(DateUtils.extractDateFromWikidataSnak(eachPropClaim.qualifiers['P580'][1]))
end
if eachPropClaim.qualifiers['P582'] and eachPropClaim.qualifiers['P582'][1] and isValueSnak(eachPropClaim.qualifiers['P582'][1]) then
after = HeDateUtils.julianToGregorian(HeDateUtils.newFromWikidataValue(eachPropClaim.qualifiers['P582'][1].datavalue.value))
--before = GregorianDate.convertToGregorianIfInInterval(DateUtils.extractDateFromWikidataSnak(eachPropClaim.qualifiers['P582'][1]))
end
end
if timestamp then
if after == nil and before and not HeDateUtils.le(timestamp, before, true) then
table.insert(bestClaims, eachPropClaim)
elseif after and before and not HeDateUtils.le(timestamp, before, true) and HeDateUtils.le(timestamp, after, true) then
table.insert(bestClaims, eachPropClaim)
elseif after and before == nil and HeDateUtils.le(timestamp, after, true) then
table.insert(bestClaims, eachPropClaim)
end
end
if not bestNoTimeClaim or mw.wikibase.entity.claimRanks['RANK_' .. mw.ustring.upper(bestNoTimeClaim.rank)] < mw.wikibase.entity.claimRanks['RANK_' .. mw.ustring.upper(eachPropClaim.rank)]
or (mw.wikibase.entity.claimRanks['RANK_' .. mw.ustring.upper(bestNoTimeClaim.rank)] < mw.wikibase.entity.claimRanks['RANK_' .. mw.ustring.upper(eachPropClaim.rank)] and not after) then
bestNoTimeClaim = eachPropClaim
end
end
end
end end
if #bestClaims == 0 and bestNoTimeClaim then
return bestNoTimeClaim
end
if #bestClaims == 1 then
return bestClaims[1]
elseif (#bestClaims > 1) and timestamp then
-- disambig: return null and log it
mw.log('לא ניתן לשייך מיקום ליישות '..entityId .. ' כיוון שקיימות מספר טענות מתאימות שנכונות ל'..timestamp:toString()..'. ניתן לציין מבחין להגדרה חד ערכית.')
return nil
else
return nil
end
end
local function missingLabelCategory(propertyName)
return '[[קטגוריה:ויקינתונים:ערכים_חסרי_תווית_בעברית: ' .. (mw.wikibase.label( propertyName) or propertyName) .. ']][[קטגוריה:ויקינתונים:ערכים_חסרי_תווית_בעברית]]'
end
p.displayFromParams = function(param, entity, timestamp, maxvalues, separator)
if param == nil then return '' end
local claims = nil
local workingEntityId = nil
local countryProperty = 'P17'
local administrativeUnitProperty = 'P131'
if type(entity) == 'table' then
workingEntityId = entity.id
claims = entity:getBestStatements(param)
else
workingEntityId = entity
if not workingEntityId then workingEntityId = mw.wikibase.getEntityIdForCurrentPage() end
if type(entity) == 'number' then workingEntityId = 'Q' .. tostring(entity) end
if workingEntityId == nil then return '' end
claims = mw.wikibase.getBestStatements(workingEntityId, param)
end
local valueList = {}
local valueCount = 0
local missingLabel = false
if claims and 0 < #claims then
for claimIdx, actualClaim in pairs(claims) do
valueCount = valueCount + 1
local locationEntitiesIds = {}
local locationNames = {}
if actualClaim.mainsnak and actualClaim.mainsnak.snaktype == 'value' and actualClaim.mainsnak.datavalue.type == 'wikibase-entityid' then
local locationEntityId = actualClaim.mainsnak.datavalue.value.id
table.insert(locationEntitiesIds, locationEntityId)
--attempt to also load administrative unit, but only if present as a qualifier
local unitQualifier = actualClaim.qualifiers and actualClaim.qualifiers[administrativeUnitProperty] and actualClaim.qualifiers[administrativeUnitProperty][1]
if unitQualifier and unitQualifier.snaktype == 'value' then
table.insert(locationEntitiesIds, unitQualifier.datavalue.value.id)
locationNames[unitQualifier.datavalue.value.id] = PropertyLink.formatEntity(unitQualifier.datavalue.value.id, false, true)
end
-- attempt to identify country in the qualifier first, but if it's not, go to the entity
local countryQualifier = actualClaim.qualifiers and actualClaim.qualifiers[countryProperty] and actualClaim.qualifiers[countryProperty][1]
local countryId = nil
local ts = nil
if countryQualifier and countryQualifier.snaktype == 'value' then
table.insert(locationEntitiesIds, countryQualifier.datavalue.value.id)
locationNames[countryQualifier.datavalue.value.id] = PropertyLink.formatEntity(countryQualifier.datavalue.value.id, false, true)
else
local countryClaim = nil
if timestamp then
if type(timestamp) == 'string' and mw.ustring.gmatch(timestamp, 'P%d+') then
local wdDates = findDateValues(timestamp, workingEntityId)
if wdDates and 0 < #wdDates then
local wdDateIdx = 1
while wdDateIdx <= #wdDates and (wdDates[wdDateIdx].claim.type ~= 'statement' or wdDates[wdDateIdx].claim.mainsnak.snaktype ~= 'value') do
wdDateIdx = wdDateIdx + 1
end
if wdDateIdx <= #wdDates and (wdDates[wdDateIdx].claim.type == 'statement' and wdDates[wdDateIdx].claim.mainsnak.snaktype == 'value') then
--wdDates[wdDateIdx] = GregorianDate.convertToGregorianIfInInterval(wdDates[wdDateIdx])
wdDates[wdDateIdx] = HeDateUtils.julianToGregorian(wdDates[wdDateIdx])
ts = wdDates[wdDateIdx]
end
end
end
if ts == nil and type(timestamp) == 'string' then
ts = HeDateUtils.parseYear(timestamp)
elseif ts == nil and type(timestamp) == 'table' and timestamp.year then
ts = timestamp
end
end
countryClaim = findClaimForTimestamp(locationEntityId, countryProperty, ts)
if countryClaim and countryClaim.mainsnak and countryClaim.mainsnak.snaktype == 'value' then
countryId = countryClaim.mainsnak.datavalue.value.id
table.insert(locationEntitiesIds, countryId)
end
end
locationEntitiesIds = TableTools.removeDuplicates(locationEntitiesIds)
local locationNamesList = {}
for _,eachLocationId in ipairs(locationEntitiesIds) do
local missingEntityLabel = false
if not locationNames[eachLocationId] then
locationNames[eachLocationId], missingEntityLabel = PropertyLink.formatEntity(eachLocationId, false, true)
mw.logObject(locationNames[eachLocationId])
missingLabel = missingLabel or missingEntityLabel
local t = Parenthesis.remove_sq_parents_internal(locationNames[eachLocationId])
-- show the offical name/short name in that timestamp
local correspondingOfficialNameClaim = findClaimForTimestamp(eachLocationId, 'P1448', ts)
if correspondingOfficialNameClaim then
locationNames[eachLocationId] = '[[' .. t .. '|' .. correspondingOfficialNameClaim.mainsnak.datavalue.value.text .. ']]'
else
local correspindingShortNameClaim = findClaimForTimestamp(eachLocationId, 'P1813', ts)
if correspindingShortNameClaim then
locationNames[eachLocationId] = '[[' .. t .. '|' .. correspindingShortNameClaim.mainsnak.datavalue.value.text .. ']]'
end
end
end
locationNames[eachLocationId] = locationNames[eachLocationId]
table.insert(locationNamesList, locationNames[eachLocationId])
end
if 0 < #locationNamesList then
table.insert(
valueList,
--appendToString({
emptyToNil({table.concat(locationNamesList, ', ')})
-- wikidata.outputReferences(actualClaim)
--})
)
end
end
end
end
if #valueList == 0 then return '' end
if separator == nil then separator = '; ' end
if maxvalues > #valueList then maxvalues = #valueList end
if missingLabel then
return table.concat(valueList, separator, 1, maxvalues) .. missingLabelCategory(param)
else
return table.concat(valueList, separator, 1, maxvalues)
end
end
p.displayFromArgs = function(args)
local param = nil
local entity = nil
local timestamp = nil
local maxvalues = 1
local separator = '; '
if args[1] or args['param'] then
param = args[1] or args['param']
end
if args[2] or args['entityId'] then
entity = args[2] or args['entityId']
end
if args[3] or args['timestamp'] then
timestamp = args[3] or args['timestamp']
end
if args[4] or args['maxvalues'] then
maxvalues = tonumber(args[4] or args['maxvalues'])
end
if args[5] or args['separator'] then
separator = args[5] or args['separator']
end
return p.displayFromParams(param, entity, timestamp, maxvalues, separator)
end
p.displayFromFrame = function(frame)
local args = getArgs(frame, { frameOnly = true })
return p.displayFromArgs(args)
end
p.displayFromParentFrame = function(frame)
local args = getArgs(frame, { parentOnly = true})
return p.displayFromArgs(args)
end
return p