Modul:Wikidata
Megjelenés
Wikidata[mi ez?] • [dokumentáció: mutat, ] • [tesztek: sikeres: 12, sikertelen: 0, kihagyva: 0 (részletek)]
Wikidata-adatok formázott megjelenítése, a {{Wikidata}}
sablon implementációja.
Wikikódból hívható függvények
formatStatements
Paraméterek
- property
- A Wikidatában tárolt tulajdonság azonosítója. Megadható névvel is. Például p856.
- value
- A Wikidatában tárolt érték helyett megjelenítendő érték.
- entityId
- A cikkhez kapcsolt Wikidata-elem helyett a megadott Wikidata-elemből olvassa ki a tulajdonság értékét.
- pageTitle
- A Wikidatához kapcsolt lap címe. Nem adható entityId-vel együtt.
- qualProp
- Állítás minősítőjének tulajdonságazonosítója. Példa: P548.
- qualValue
- A szűrésnél alkalmazott érték. Több érték is adható, vesszővel elválasztva. Példa: Q3295609,Q51930650,Q2122918,Q21727724,Q1072356.
- direction
- Koordináták dimenziója. Értéke latitude, longitude vagy both lehet: az első kettő a további gépi feldolgozásra alkalmas számot adja vissza, a harmadik a Modul:Coordinate segítségével formázott eredményt ad.
- link
- Értéke nem, ha azt szeretnénk, hogy a függvény értéke ne link legyen, hanem csak a címke; csak, ha pedig azt szeretnénk, hogy csak a kapcsolt Wikipédia-szócikk.
- externalId
- Helyileg megadott külső azonosító formázása Wikidata helyett. Külső azonosítóknál ezt kell megadni második paraméter helyett!
- externalIdLabel
- Külső azonosítóhoz tartozó hivatkozás megjelenítési szövege.
- link szövege
- URL típusú tulajdonság hivatkozásának megjelenő szövege. Visszamenőleges kompatibilitás miatt
format=wikilink
beállítást tesz szükségessé. Üres érték esetén számozott hivatkozás jelenik meg. Ha csakformat
van megadva, a tulajdonság neve lesz a szöveg. - lang
- A címke nyelvének megadása, több nyelv esetén vesszővel elválasztva, szóköz nélkül, ekkor az első olyan nyelven jeleníti meg a címkét, amin létezik. Alapértelmezetten
hu,en
. Nyelvvel jelölt szövegek (monolingual text) esetén a nyelv szűrőfeltétele.all
értékkel nincs szűrés. - first
- Ha azt szeretnénk, hogy csak egy értéket adjon vissza, például képeknél.
- showQualifiers
- Összes minősítő megjelenítése, vagy megadott minősítők megjelenítése (ha a paraméterérték tulajdonságazonosítók listája, pl.
P580, P582
). - showReferences
- Forráshivatkozások megjelenítése. Alapértelmezetten legfeljebb 5 forráshivatkozás jelenik meg; ha a paraméter értéke egy pozitív egész szám, akkor annyi a limit, ha 0, akkor pedig az összes (esetenként több tucat!) forráshivatkozás megjelenik.
- rank
- Értékei: preferred, normal, deprecated, all, valid. Ha nincs megadva, akkor a legmagasabb rangúakat adja vissza. A valid a preferred és a normal együttesen.
- életkor
- Értéke igen.
- felsorolás
- Az értékek felsorolásának típusa:
- lista
- pöttyözött lista
- számozott lista
- számozott lista
- sorok
- több érték esetén felsorolásjel nélküli lista, egy érték esetén sima szöveg (alapértelmezett)
- szöveg
- folyószöveg (értékek között vesszővel, utolsó érték előtt „és”-sel)
- table
- Lua-tömb
- lenyíló
- Hosszú listák megjelenítése nyitható listaként. Értéke egy szám. Ha a listának több eleme van, akkor nyitható listaként fog megjelenni. Lista, számozott lista és sorok felsorolásnál használható. Példa: Földközi-tenger.
- format
-
- raw
- tárolt érték formázás nélkül
- default
- népesség formázása a
{{Népesség}}
(?) sablon alapmegjelenítése szerint - iso
- dátum ISO 8601 formátumban
- date-object
- dátum a Modul:Time objektumával (csak modulból hívva van értelme)
- percentage
- számok megjelenítése százalékként
- url
- URL, például külső azonosító címe
- wikilink
- URL típusú tulajdonság formázása wikiszöveges külső hivatkozásként
- unit
- mennyiség mértékegysége. A lehetséges értékei a Modul:Convert/data modulban láthatóak. Például
km2
. Egyszerre több mértékegységben is meg tudja jeleníteni a mennyiséget. Ehhez a mértékegységeket+
jellel kell felsorolni. Példáulkm+mi
. - showUnit
- mértékegység megjelenítése a paraméter jelenléte esetén
- roundDec
- hány tizedesre kerekítse az átalakított értéket
- sort
- Rendezés több érték estén: üres vagy logikai igaz esetén címke szerint,
Pxxx
esetén aPxxx
minősítő szerint (a megadott minősítőket előre rendezve), egyébként a sort függvénnyel. sortDesc paraméter jelenléte esetén csökkenő sorrendben történik a rendezés. - sortDesc
- Rendezés csökkenő sorrendben. A paraméter jelenléte esetén csökkenő sorrendben történik a rendezés, különben növekvő sorrendben.
- dateformat
- Dátumformátum a
{{#time:}}
értelmezőfüggvénynek (csak a népesség dátumánál működik, más helyzetben a változó pontosság – napra pontostól az évmilliárdig bármi lehet – és a függvény behatároltsága – csak 111-től 9999-ig értelmezi az éveket – miatt nincs értelme megadni egy fix formátumot). - punctuation
- Központozás az utolsó érték és esetleges minősítői után, de a hozzá tartozó forráshivatkozás előtt. Általában felsorolás=lista esetén van értelme.
containsProperty
Wikidata-tulajdonság meglétének vizsgálata. Lásd {{Wikidata-f}}
.
Luából hívható függvények
containsPropertyWithValue
Tulajdonág értékének vizsgálata.
withHighestRank
Tulajdonság értékeinek szűrése a legmagasabb fokozattal (rank) rendelkező értékekre.
formatStatement
Tulajdonság egy értékének formázott megjelenítése.
Használt modulok, sablonok
- Modul:Arguments – paraméterek beolvasásához
- Modul:Time – dátum kiírásához (formázottan)
{{plainlist}}
– alapértelmezett kimenetnél a többelemű listák formázásához
require('strict')
local p = {}
local getArgs = require('Modul:Arguments').getArgs
local framel = mw.getCurrentFrame()
local formatStatements
local i18n = {
['errors'] = {
['property-param-not-provided'] = "Hiányzó ''property='' paraméter",
['property-not-found'] = 'Érvénytelen tulajdonság: %s',
['entity-not-found'] = 'Nem létező Wikidata-elem',
['unknown-claim-type'] = 'Ismeretlen az állítás típusa',
['unknown-snak-type'] = 'Ismeretlen a snak típusa',
['unknown-datavalue-type'] = 'Ismeretlen az érték típusa',
['unknown-entity-type'] = 'Ismeretlen a Wikidata-elem típusa',
['unknown-value-module'] = "A ''value-module'' és ''value-function'' paramétert egyszerre kell beállítani",
['value-module-not-found'] = "A ''value-module'' nem létező modulra mutat",
['value-function-not-found'] = "A ''value-function'' nem létező funkcióra mutat",
['globecoordinate-direction'] = "Az érték típusa ''globecoordinate:'' kell ''direction=latitude'', ''longitude'' vagy ''both''",
['invalid-value'] = 'Érvénytelen érték',
['unknown-unit'] = 'Ismeretlen mértékegység: %s',
['excluding-arguments'] = 'Nem adható %s és %s egyidejűleg',
},
['somevalue'] = "''nem ismert''",
['novalue'] = "''nincs''"
}
local citeTemplateArgs = {
cite_web = {
title = 'Cite web',
args = {
P50 = 'author',
P407 = 'language',
P248 = 'website',
P304 = 'pages',
P123 = 'publisher',
P577 = 'date',
P1065 = 'archiveurl',
P2960 = 'archivedate',
P356 = 'doi',
P813 = 'accessdate',
P1683 = 'quote'
}
},
cite_journal = {
title = 'Cite journal',
args = {
P50 = 'author',
P577 = 'date',
P407 = 'language',
P1433 = 'journal',
P291 = 'location',
P478 = 'volume',
P433 = 'issue',
P304 = 'pages',
P123 = 'publisher',
P1065 = 'archiveurl',
P2960 = 'archivedate',
P356 = 'doi',
P236 = 'issn',
P888 = 'jstor',
P698 = 'pmid',
P932 = 'pmc',
P813 = 'accessdate',
P1683 = 'quote'
}
},
cite_book = {
title = 'CitLib',
args = {
P50 = 'aut',
P2093 = 'aut',
P393 = 'edi',
P291 = 'loc',
P123 = 'red',
P577 = 'ann',
P179 = 'ser',
P957 = 'isbn',
P212 = 'isbn',
P792 = 'cap',
P478 = 'vol',
P304 = 'pag',
P813 = 'accd',
P407 = 'lan',
P1065 = 'aurl',
P2960 = 'archd',
P655 = 'ass',
P98 = 'ass'
}
},
}
-- In addition to url, title, author
local function formatError(key, ...)
error(i18n.errors[key]:format(...), 2)
end
function p.getUpperLevelOfType(property, typeId, entityId, item)
local result, statements, visited = {}, {}, {[item and item.id or entityId] = true}
local function getStatements(aEntityId, aItem)
local wb_statements
if aItem then
wb_statements = aItem:getBestStatements(property)
elseif aEntityId then
wb_statements = mw.wikibase.getBestStatements(aEntityId, property)
else
return
end
for _, s in ipairs(wb_statements) do
if s.mainsnak.snaktype == 'value' then
local itemId = 'Q' .. s.mainsnak.datavalue.value['numeric-id']
if not visited[itemId] then
visited[itemId] = true
local item2 = mw.wikibase.getEntity(itemId)
if p.containsPropertyWithValue(item2, 'P31', typeId) then
statements[item2.id] = s
else
getStatements(nil, item2)
end
end
end
end
end
getStatements(entityId, item)
for _, s in pairs(statements) do
table.insert(result, s)
end
return result
end
local function firstValue(statements)
for _, statement in ipairs(statements) do
if statement.rank == 'preferred' then
return {statement}
end
end
for _, statement in ipairs(statements) do
if statement.rank == 'normal' then
return {statement}
end
end
return {}
end
local function withRank(statements, ranks)
local result = {}
for _, statement in ipairs(statements) do
for _, rank in ipairs(ranks) do
if statement.rank == rank then
table.insert(result, statement)
break
end
end
end
return result
end
function p.withHighestRank(statements)
local preferred, normal = {}, {}
for _, statement in ipairs(statements) do
if statement.rank == 'preferred' then
table.insert(preferred, statement)
elseif statement.rank == 'normal' then
table.insert(normal, statement)
end
end
return #preferred > 0 and preferred or normal
end
local function atDate(statements, date)
local result = {}
local Time = require('Modul:Time')
local time = Time.newFromIso8601(date, true)
if not time then
return statements
end
local isQualified = false
for _, s in ipairs(statements) do
local startDate, endDate
if s.qualifiers and s.qualifiers.P580 and #s.qualifiers.P580 == 1 and s.qualifiers.P580[1].snaktype == 'value' then
startDate = Time.newFromWikidataValue(s.qualifiers.P580[1].datavalue.value)
end
if s.qualifiers and s.qualifiers.P582 and #s.qualifiers.P582 == 1 and s.qualifiers.P582[1].snaktype == 'value' then
endDate = Time.newFromWikidataValue(s.qualifiers.P582[1].datavalue.value)
end
if startDate or endDate then
isQualified = true
end
if not startDate and endDate and time <= endDate or
startDate and not endDate and startDate <= time or
startDate and endDate and startDate <= time and time <= endDate then
table.insert(result, s)
end
end
if isQualified then
return result
else
return statements
end
end
local function getEntityIdFromValue(value)
local prefix
if value['entity-type'] == 'item' then
prefix = 'Q'
elseif value['entity-type'] == 'property' then
prefix = 'P'
else
formatError('unknown-entity-type')
end
return prefix .. value['numeric-id']
end
local function getChrDates(chrDate, entityId)
if not chrDate then
return {}
end
if chrDate:match('^P%d+$') then
local dates = mw.wikibase.getEntity(entityId):getBestStatements(chrDate)
local ret = {}
for _, v in ipairs(dates) do
if v.mainsnak.snaktype == 'value' then
table.insert(ret, v.mainsnak.datavalue.value.time)
end
end
return ret
else
return { chrDate }
end
end
local function getChrQualifierDates(chrQualifierDate, statement)
if not chrQualifierDate or not chrQualifierDate:match('^P%d+$') then
return {}
end
if not statement.qualifiers or not statement.qualifiers[chrQualifierDate] then
return {}
end
local ret = {}
for _, v in ipairs(statement.qualifiers[chrQualifierDate]) do
if v.snaktype == 'value' then
table.insert(ret, v.datavalue.value.time)
end
end
return ret
end
local function getDatedStatement(dates, options, dateFields, item)
if not dateFields then
dateFields = { 'atDate' }
end
local result, conflict = nil, false
for _, v in ipairs(dates) do
for _, w in ipairs(dateFields) do
options[w] = v
end
local statement = formatStatements(options, item)
if statement == '' then
statement = nil
end
if statement and result == nil then
result = statement
elseif statement ~= result then
conflict = true
end
end
if not conflict then
return result
else
return nil
end
end
local function formatEntityId(entityId, options, statement)
local link = mw.wikibase.sitelink(entityId)
if options.link == 'csak' then
return link
end
if link and options.link ~= 'nem' and mw.ustring.sub(link, 1, 10) == 'Kategória:' then
return '[[' .. link .. ']]'
end
local label
if options.lang then
for lang in mw.text.gsplit(options.lang, ',') do
label = mw.wikibase.getLabelByLang(entityId, lang)
if label then
break
end
end
else
label = mw.wikibase.label(entityId)
end
if options.labelProperty and options.labelProperty ~= '' then
local options2 = {}
for k, v in pairs(options) do
if k ~= 'labelProperty' then
options2[k] = v
end
end
options2.property = options.labelProperty
options2.entityId = entityId
options2.rank = 'valid'
options2.link = 'nem'
options2.lang = options.lang or 'hu'
options2.firstAfter = true
options2['felsorolás'] = nil -- felsorolásjel nélkül
local label2 = formatStatements(options2)
if label2 and label2 ~= '' then
label = label2
end
end
if options.chrProperty then
local dates
if options.chrDate then
dates = getChrDates(options.chrDate, options.entityId)
elseif options.chrQualifierDate and statement then
dates = getChrQualifierDates(options.chrQualifierDate, statement)
else
-- getDatedStatement with an empty date object is a no-op
-- this should not happen if the module is used correctly
dates = {}
end
local chrLabel = getDatedStatement(dates, {
property = options.chrProperty,
entityId = entityId,
rank = 'valid',
lang = options.lang or 'hu',
firstAfter = true,
['felsorolás'] = nil -- felsorolásjel nélkül
})
if chrLabel then
label = chrLabel
end
end
if label and options.format == 'ucfirst' then
label = mw.language.getContentLanguage():ucfirst(label)
end
if link and options.link ~= 'nem' then
if label then
if mw.ustring.sub(label, 2) == mw.ustring.sub(link, 2) and
mw.ustring.lower(mw.ustring.sub(label, 1, 1)) == mw.ustring.lower(mw.ustring.sub(link, 1, 1)) then
return '[[' .. label .. ']]'
else
return '[[' .. link .. '|' .. label .. ']]'
end
else
return '[[' .. link .. ']]'
end
else
return label or link --TODO what if no links and label + fallback language?
end
end
local function formatTimeValue(value, options)
if options.format == 'raw' then
return value.time
else
local time = require('Modul:Time').newFromWikidataValue(value)
if time then
if options.format == 'iso' then
return tostring(time)
elseif options.format == 'date-object' then
return time
end
return time:formatDate(options)
else
formatError('invalid-value')
end
end
end
local function countryOf(itemId, options, noselflink, chrDate)
local function getStatement(dates, new_options, item)
return getDatedStatement(dates, new_options, { 'atDate', 'chrDate' }, item) or formatStatements(new_options, item)
end
if not itemId then
return nil
end
local item = mw.wikibase.getEntity(itemId)
if not item then
return nil
end
local dates = getChrDates(chrDate, options.entityId)
local new_options = {
property = 'P17',
chrProperty = options.chrProperty,
format = 'raw'
}
if noselflink and item.id == getStatement(dates, new_options, item) then
return nil
end
new_options.format = nil
return getStatement(dates, new_options, item)
end
local function formatNum(amount)
if amount < 10000 and -10000 < amount then
return tostring(amount):gsub('%.', ',')
else
return mw.getContentLanguage():formatNum(amount)
end
end
local function formatDatavalue(datavalue, options, statement)
--Use the customize handler if provided
if options['value-module'] or options['value-function'] then
if not options['value-module'] or not options['value-function'] then
return formatError( 'unknown-value-module' )
end
local formatter = require ('Module:' .. options['value-module'])
if formatter == nil then
return formatError( 'value-module-not-found' )
end
local fun = formatter[options['value-function']]
if fun == nil then
return formatError( 'value-function-not-found' )
end
return fun( datavalue.value, options )
end
--Default formatters
if datavalue.type == 'wikibase-entityid' then
local itemId = getEntityIdFromValue(datavalue.value)
if options.format == 'raw' then
return itemId
end
local result = formatEntityId(itemId, options, statement)
if not result then
return nil
end
local country = options.format == 'with_country' and countryOf(itemId, options, true, options.chrDate)
return result .. (country and ', ' .. country or '')
elseif datavalue.type == 'string' then
return datavalue.value --TODO ids + media
elseif datavalue.type == 'time' then
return formatTimeValue(datavalue.value, options)
elseif datavalue.type == 'globecoordinate' then
if options.format == 'geohack' then
return '[[Fájl:OOjs UI icon mapPin-progressive.svg|16px|link=]] ' .. require('Modul:Coordinate').coord {
datavalue.value.latitude,
datavalue.value.longitude,
options.meta,
precision = 'wikidata',
format = 'dms'
}
end
if options.direction == 'latitude' then
return datavalue.value.latitude
elseif options.direction == 'longitude' then
return datavalue.value.longitude
else
return formatError('globecoordinate-direction')
end
elseif datavalue.type == 'quantity' then
if options.format == 'raw' then
return datavalue.value.amount
end
local result
local amount = tonumber(datavalue.value.amount)
if datavalue.value.unit == '1' then
if options.unit then
return nil
end
if options.format == 'percentage' then
result = formatNum(amount * 100) .. '%'
else
result = formatNum(amount)
end
else
local unitId = datavalue.value.unit:match('Q%d+')
local sourceUnit = mw.loadData('Modul:Wikidata/units').wikidata_item_ids[unitId]
if not sourceUnit then
if not options.unit and unitId then
local sym_hu, sym_mul
for _, st in ipairs(mw.wikibase.getBestStatements(unitId, 'P5061')) do -- unit symbol
sym_hu = p.formatStatement(st, { lang = 'hu' })
if sym_hu then
break
end
sym_mul = sym_mul or p.formatStatement(st, { lang = 'mul' })
end
sym_hu = sym_hu or sym_mul
result = formatNum(amount) .. (unitId ~= 'Q28390' and ' ' or '') .. (sym_hu or mw.wikibase.getLabel(unitId) or unitId)
else
formatError('unknown-unit', unitId or 'nil')
end
else
local targetUnit = options.unit or sourceUnit
-- Help: [[:en:Help:Convert]]
result = require('Modul:Convert')._convert {
amount,
sourceUnit,
targetUnit,
options.roundDec ~= '' and options.roundDec or nil, -- round output to N decimal places
disp = options.showUnit and 'out' or 'number'
}
end
end
return result
elseif datavalue.type == 'monolingualtext' then
local langs = options.lang or 'hu'
if langs == 'all' or langs == '~hu' and datavalue.value.language ~= 'hu' then
return datavalue.value.text
end
for lang in mw.text.gsplit(langs, ',') do
if lang:match('^%s*(.-)%s*$') == datavalue.value.language then
return datavalue.value.text
end
end
return nil
else
formatError('unknown-datavalue-type')
end
end
local function formatExternalId(options, externalId)
if options.format == 'raw' then
return externalId
end
local formatterUrl = formatStatements {
entityId = options.property,
property = 'P1630', -- formatter URL
first = true
}
if not formatterUrl then
return externalId
end
local url = formatterUrl:gsub('%$1', ((mw.uri.encode(externalId, 'PATH'):gsub('%%2F', '/')):gsub('%%', '%%%%')))
if options.format == 'url' then
return url
end
return string.format('[%s %s]', url, options.externalIdLabel ~= '' and options.externalIdLabel or externalId)
end
local function formatUrl(url, property, options)
if not options or not options.format or options.format == 'raw' or options.format == 'url' then
return url
end
if options.format == 'wikilink' then
return ('[%s %s]'):format(url, options['link szövege'] or mw.wikibase.getLabel(property))
end
return nil
end
-- Format an arbitrary snak. Parameters:
-- snak: the snak to format (required)
-- aOptions: a table of formatting options (optional)
-- statement: the statement of which this snak is the main snak of,
-- if it’s a main snak (optional)
local function formatSnak(snak, aOptions, statement)
local options = aOptions or {}
if snak.snaktype == 'somevalue' then
return options.somevalue or (options.format == 'raw' and 'somevalue' or i18n['somevalue'])
elseif snak.snaktype == 'novalue' then
return options.format == 'raw' and 'novalue' or i18n['novalue']
elseif snak.snaktype == 'value' then
if options['value-module'] or options['value-function'] then
return formatDatavalue(snak.datavalue, options, statement)
end
if snak.datatype == 'math' then
return framel:extensionTag('math', snak.datavalue.value)
elseif snak.datatype == 'external-id' then
return formatExternalId(options, snak.datavalue.value)
elseif snak.datatype == 'url' then
return formatUrl(snak.datavalue.value, snak.property, options)
else
return formatDatavalue(snak.datavalue, options, statement)
end
else
formatError('unknown-snak-type')
end
end
--[[
Empty string result used in concatenations.
]]
local function formatSnaks(snaks, options)
local formattedSnaks = {}
for _, snak in ipairs(snaks) do
table.insert(formattedSnaks, formatSnak(snak, options))
end
return mw.text.listToText(formattedSnaks, options.separator, options.conjunction)
end
--[=[
Implementation guidelines: [[d:Help:Sources]], [[:en:Module:Wd#References]]
--]=]
local function formatReference(reference, options)
local statedInItemId
local args = {}
local result = {}
local tplId = 'cite_web'
local statedInItem
local function formatProperty(prop, prop2, dashSeparated, extraOptions)
local localOptions = extraOptions or {}
if dashSeparated then
localOptions['felsorolás'] = nil
localOptions.separator = ' – '
localOptions.conjunction = ' – '
else
localOptions['felsorolás'] = 'szöveg'
end
local formatted = reference.snaks[prop] and formatSnaks(reference.snaks[prop], localOptions)
if formatted and formatted ~= '' then
return formatted
end
if prop2 then
formatted = reference.snaks[prop2] and formatSnaks(reference.snaks[prop2], localOptions)
if formatted and formatted ~= '' then
return formatted
end
end
if statedInItem then
localOptions.property = prop
formatted = formatStatements(localOptions, statedInItem)
if formatted and formatted ~= '' then
return formatted
end
if prop2 then
localOptions.property = prop2
return formatStatements(localOptions, statedInItem)
end
end
return nil
end
local function formatFirstValue(entityId, propertyId)
local lOptions = {}
for _, s in ipairs(mw.wikibase.getBestStatements(entityId, propertyId)) do
if s.mainsnak.snaktype == 'value' then
if propertyId == 'P407' then -- [[d:Property:P407]] language of work or name (Item)
-- [[d:Property:P218]] ISO 639-1 code (External identifier)
return formatStatements { entityId=s.mainsnak.datavalue.value.id, property='P218', format='raw', first=true, excludespecial=true }
end
if s.mainsnak.datatype == 'time' then
lOptions = { link = 'nem' }
end
return p.formatStatement(s, lOptions)
end
end
return nil
end
statedInItemId = reference.snaks.P248 and reference.snaks.P248[1].snaktype == 'value' and reference.snaks.P248[1].datavalue.value.id or nil
if statedInItemId then
if p.isOfType(statedInItemId, 'Q191067') then -- [[d:Q191067]] article
tplId = 'cite_journal'
local publishedInItemId
for _, s in ipairs(mw.wikibase.getBestStatements(statedInItemId, 'P1433')) do -- [[d:Property:P1433]] published in (Item)
if s.mainsnak.snaktype == 'value' then
publishedInItemId = s.mainsnak.datavalue.value.id
break
end
end
if publishedInItemId then
for property, arg in pairs(citeTemplateArgs[tplId].args) do
args[arg] = formatFirstValue(publishedInItemId, property)
end
end
elseif p.isOfType(statedInItemId, 'Q571') then -- [[d:Q571]] book
tplId = 'cite_book'
end
for property, arg in pairs(citeTemplateArgs[tplId].args) do
args[arg] = formatFirstValue(statedInItemId, property)
end
end
local excluded = true
for key, referenceSnaks in pairs(reference.snaks) do
-- exclude "imported from Wikimedia project", "Wikimedia import URL" and "inferred from"
if key ~= 'P143' and key ~= 'P4656' and key ~= 'P3452' then
-- don't show references with nothing more than an access date
if key ~= 'P813' then
excluded = false
end
if key == 'P407' then -- [[d:Property:P407]] language of work or name (Item)
local formattedSnak = formatSnaks(referenceSnaks, { link = 'nem' })
if formattedSnak ~= 'magyar' and formattedSnak ~= '' then
table.insert(result, formattedSnak)
args[citeTemplateArgs[tplId].args[key]] = formattedSnak
end
else
for _, snak in ipairs(referenceSnaks) do
if snak.snaktype == 'value' then
local refOptions = { property = snak.property }
if snak.datatype == 'time' then
refOptions.link = 'nem'
end
local formattedSnak = formatSnak(snak, refOptions)
table.insert(result, formattedSnak)
if citeTemplateArgs[tplId].args[snak.property] then
args[citeTemplateArgs[tplId].args[snak.property]] = formattedSnak
end
end
end
end
end
end
if args.language == 'hu' then
args.language = nil
end
if args.lan == 'hu' then
args.lan = nil
end
local url_source = 'reference'
args.url = reference.snaks['P854'] and formatSnak(reference.snaks['P854'][1]) -- [[d:Property:P854]] reference URL (URL)
if reference.snaks.P1476 then
for _, snak in ipairs(reference.snaks.P1476) do
if not args.title or (snak.datavalue and snak.datavalue.value.language == 'hu') then
args.title = snak.datavalue.value.text
end
end
for _, snak in ipairs(args.title and reference.snaks.P1680 or {}) do -- [[d:Property:P1680]] subtitle (Monolingual text)
if snak.datavalue and snak.datavalue.value.language == 'hu' then
args.title = args.title .. ': ' .. snak.datavalue.value.text
break
end
end
end
statedInItem = reference.snaks.P248 and
reference.snaks.P248[1].snaktype == 'value' and
mw.wikibase.getEntity(reference.snaks.P248[1].datavalue.value.id) or
nil
if not args.title and statedInItem then
args.title = formatStatements({
property = 'P1476', -- [[d:Property:P1476]] title (Monolingual text)
lang = 'all',
first = true
}, statedInItem)
if args.title then
local subtitle = formatFirstValue(statedInItemId, 'P1680') -- [[d:Property:P1680]] subtitle (Monolingual text)
if subtitle then
args.title = args.title .. ': ' .. subtitle
end
end
end
if not args.title and statedInItem then
args.title = formatSnaks(reference.snaks.P248, { link = 'nem' })
if args.title == '' then
args.title = nil
end
end
if args.website == args.title then
args.website = nil
end
if not args.url and statedInItem then
local id_property
for _, statement in ipairs(mw.wikibase.getBestStatements(statedInItem.id, 'P1687')) do -- [[d:Property:P1687]] Wikidata property (Property)
if statement.mainsnak.snaktype == 'value' and (reference.snaks[statement.mainsnak.datavalue.value.id] or
next(mw.wikibase.getBestStatements(options.entityId, statement.mainsnak.datavalue.value.id))) then
id_property = statement.mainsnak.datavalue.value.id
break
end
end
if not id_property then
for _, statement in ipairs(mw.wikibase.getBestStatements(statedInItem.id, 'P527')) do -- [[d:Property:P527]] has part(s) (Item)
if statement.mainsnak.snaktype == 'value' then
id_property = formatStatements{
entityId = statement.mainsnak.datavalue.value.id,
property = 'P1687',
first = true,
excludespecial = true,
format = 'raw'
}
if id_property then
break
end
end
end
end
if id_property then
url_source = 'external_id'
local fs_options = { property = id_property, first = true, excludespecial = true, format = 'url' }
if reference.snaks[id_property] then
args.url = formatSnak(reference.snaks[id_property][1], fs_options)
else
-- Get property from item instead of reference
fs_options.entityId = options.entityId
args.url = formatStatements(fs_options)
end
end
end
if not args.url and statedInItem then
url_source = 'stated_in'
args.url = formatStatements({
property = 'P953', -- [[d:Property:P953]] full work available at URL (URL)
first = true,
excludespecial = true
}, statedInItem)
if not args.url then
args.url = formatStatements({
property = 'P856', -- [[d:Property:P856]] official website (URL)
first = true,
excludespecial = true
}, statedInItem)
end
end
if url_source ~= 'external_id' then
args.author = formatProperty('P50', 'P2093', true)
end
--[=[ Final fixes ]=]
if args.url and args.url:match('^https?://www.ksh.hu') then
args.url = args.url:gsub('p_lang=EN', 'p_lang=HU')
end
if args.url and args.url:match('^https://nepszamlalas2022.ksh.hu') then
args.url = args.url:gsub('en/database', 'adatbazis')
end
args.url = url_source == 'reference' and args.url or args.archiveurl or args.url
args.title = args.title or args.url
args.archiveurl = args.archivedate and args.archiveurl or nil
args.archivedate = args.archiveurl and args.archivedate or nil
if tplId == 'cite_book' then
args.tit = args.title
args.subtit = args.subtitle
args.title = nil
args.subtitle = nil
end
if tplId ~= 'cite_web' or args.url and args.title then
return framel:expandTemplate { title = citeTemplateArgs[tplId].title, args = args }
end
if excluded then
return nil
end
return table.concat(result, ', ')
end
local function formatReferences(references, options)
if not references then
return ''
end
local limit = tonumber(options.showReferences) or 5
local formattedReferences = {}
for _, reference in ipairs(references) do
if limit == 0 or #formattedReferences < limit then
local formattedReference = formatReference(reference, options)
if formattedReference and formattedReference ~= '' then
table.insert(formattedReferences, framel:extensionTag('ref', formattedReference, {name = reference.hash}))
end
end
end
return table.concat(formattedReferences)
end
local function populationWithPointInTime(statement, options, last)
if statement.mainsnak.snaktype ~= 'value' then
return nil
end
local population = tonumber(statement.mainsnak.datavalue.value.amount)
local text = (population < 10000 and tostring(population) or mw.getContentLanguage():formatNum(population)) .. ' fő'
if statement.qualifiers and statement.qualifiers.P585 and statement.qualifiers.P585[1].snaktype == 'value' then -- dátum
local time = require('Modul:Time').newFromWikidataValue(statement.qualifiers.P585[1].datavalue.value)
local fDate
if time.precision >= 11 then
fDate = mw.getContentLanguage():formatDate(options.dateformat or 'Y. M. j.', time:toIso8601())
else
fDate = tostring(time.year)
end
text = text .. ' ' .. mw.text.tag('span', {style = 'font-size:90%; white-space:nowrap;'}, '(' .. fDate .. ')')
end
if last and options.punctuation then
text = text .. options.punctuation
end
text = text .. formatReferences(statement.references, options)
local qid = statement.id:match("^[Qq]%d+"):upper()
if qid == mw.wikibase.getEntityIdForCurrentPage() then
return text
end
if last then
text = text .. string.format(' <small class="plainlinks noexcerpts">[https://www.wikidata.org/wiki/%s?uselang=hu#P1082 +/-]</small>', qid)
end
return text
end
local function sortAuxiliary(statements, propGenerator, sortDesc)
local newlist, auxlist = {}, {}
local function sort(a, b)
if a.prop and b.prop and a.prop ~= b.prop then
return a.prop < b.prop
elseif a.prop and b.prop then
return a.i < b.i
elseif a.prop or b.prop then
return not a.prop
else
return a.i < b.i
end
end
for i, v in ipairs(statements) do
auxlist[i] = {
i = i,
prop = propGenerator(v, i)
}
end
if sortDesc then
table.sort(auxlist, function (a, b)
return not sort(a, b)
end)
else
table.sort(auxlist, sort)
end
for _, v in ipairs(auxlist) do
table.insert(newlist, statements[v.i])
end
return newlist
end
local function getSortableValue(snak)
if not snak or snak.snaktype ~= 'value' then
return nil
end
local datavalue = snak.datavalue
if datavalue.type == 'wikibase-entityid' then
local id = 'Q' .. datavalue.value['numeric-id']
local key = mw.wikibase.label(id)
if not key then
key = mw.wikibase.sitelink(id)
end
if not key then
return id
end
return mw.language.getContentLanguage():caseFold(key)
elseif datavalue.type == 'string' then
return datavalue.value
elseif datavalue.type == 'time' then
return require('Modul:Time').newFromWikidataValue(datavalue.value)
elseif datavalue.type == 'quantity' then
return tonumber(datavalue.value.amount)
elseif datavalue.type == 'monolingualtext' then
return datavalue.value.text
end
return nil
end
local function sortByValue(statements, sortDesc)
local function propGenerator(v)
return getSortableValue(v.mainsnak)
end
return sortAuxiliary(statements, propGenerator, sortDesc)
end
local function sortByQualifier(statements, qualifier, sortDesc)
local function propGenerator(v)
return v.qualifiers and v.qualifiers[qualifier] and getSortableValue(v.qualifiers[qualifier][1])
end
return sortAuxiliary(statements, propGenerator, sortDesc)
end
local function filterByQualifier(options, statements)
if not options.qualProp then
return statements
end
local result = {}
options.qualProp = (options.qualProp):upper()
for _, s in ipairs(statements) do
if s.qualifiers and s.qualifiers[options.qualProp] then
if not options.qualValue then
table.insert(result, s)
else
for _, snak in ipairs(s.qualifiers[options.qualProp]) do
if snak.snaktype == 'value' then
if snak.datavalue.type == 'wikibase-entityid' and ((options.qualValue):upper() .. ','):find(snak.datavalue.value.id .. ',', 1, true) or
snak.datavalue.type == 'string' and (options.qualValue .. ','):find(snak.datavalue.value .. ',', 1, true) then
table.insert(result, s)
break
end
end
end
end
end
end
return result
end
--[[
Local function with forward declaration
--]]
function formatStatements(options, item)
if not options.property or options.property == '' then
formatError('property-param-not-provided')
end
local property = mw.wikibase.resolvePropertyId(options.property)
if not property then
formatError('property-not-found', options.property)
end
--Get entity
local entity = item
local statements = {}
if entity then
statements = entity:getAllStatements(property)
else
if options.entityId and options.pageTitle then
return formatError('excluding-arguments', 'entityId', 'pageTitle')
end
if options.pageTitle then
options.entityId = mw.wikibase.getEntityIdForTitle(options.pageTitle)
elseif not options.entityId then
options.entityId = mw.wikibase.getEntityIdForCurrentPage()
end
if not options.entityId then
return options['felsorolás'] == 'table' and {} or nil
end
if mw.wikibase.isValidEntityId(options.entityId) then
statements = mw.wikibase.getAllStatements(options.entityId, property)
end
end
if #statements == 0 then
return options['felsorolás'] == 'table' and {} or nil
end
if options.atDate then
statements = atDate(statements, options.atDate)
end
-- TODO Extract selection and filtering
if options.rank ~= 'all' then
if not options.rank then
statements = p.withHighestRank(statements)
elseif options.rank == 'valid' then
statements = withRank(statements, {'normal', 'preferred'})
else
statements = withRank(statements, {options.rank})
end
end
if options.typeId then
statements = p.getUpperLevelOfType(property, options.typeId, options.entityId, entity)
end
if options.excludespecial then
local newStatements = {}
for _, s in ipairs(statements) do
if s.mainsnak.snaktype == 'value' then
table.insert(newStatements, s)
end
end
statements = newStatements
end
statements = filterByQualifier(options, statements)
if options['filter-function'] then
statements = require('Modul:Wikidata/filters')[options['filter-function']](statements)
end
if options.sort then
local comp = options.sort
if type(comp) == 'string' and comp:match('[Pp]%d+') then
statements = sortByQualifier(statements, string.upper(comp), options.sortDesc)
elseif comp == '' or comp == true then
statements = sortByValue(statements, options.sortDesc)
else
table.sort(statements, comp)
end
end
if options.first then
statements = firstValue(statements)
end
--Format statement and concat them cleanly
local formattedStatements = {}
-- loop variable to know if we're processing the last statement
local i = 0
for _, statement in ipairs(statements) do
i = i + 1
local fs
if property == 'P1082' and options.format == 'default' then -- population
fs = populationWithPointInTime(statement, options, (i == #statements))
else
fs = p.formatStatement(statement, options, (i == #statements))
end
if fs then
if options['felsorolás'] == 'lista' then
fs = '* ' .. fs
elseif options['felsorolás'] == 'számozott lista' then
fs = '# ' .. fs
end
table.insert(formattedStatements, fs)
end
end
local function collapsibleList(frame, args, list, size)
if args['lenyíló'] and size > tonumber(args['lenyíló']) then
return frame:expandTemplate{ title = 'Show', args = { 'Lista', list } }
end
return list
end
local function plainlist(items)
if #items == 0 then
return nil
end
if #items == 1 then
return items[1]
end
return collapsibleList(framel, options, framel:expandTemplate{ title = 'Plainlist', args = { '\n* ' .. table.concat(items, '\n* ') .. '\n' } }, #items)
end
if options['felsorolás'] == 'lista' or options['felsorolás'] == 'számozott lista' then
return collapsibleList(framel, options, table.concat(formattedStatements, '\n'), #formattedStatements)
elseif options['felsorolás'] == 'sorok' then
return plainlist(formattedStatements)
elseif options['felsorolás'] == 'szöveg' then
return mw.text.listToText(formattedStatements)
elseif options['felsorolás'] == 'table' then
return formattedStatements
elseif options.separator or options.conjunction then
options.separator = options.separator and string.gsub(options.separator, ' ', ' ')
options.conjunction = options.conjunction and string.gsub(options.conjunction, ' ', ' ')
return mw.text.listToText(formattedStatements, options.separator, options.conjunction)
else
if options.firstAfter then
return formattedStatements[1] or ''
end
return plainlist(formattedStatements)
end
end
local function formatQualifiers(statement, _, qualifiers)
local result, orderedResult, startDate, endDate = {}, {}
local function getInterval()
if startDate and startDate ~= '' or endDate and endDate ~= '' then
local dash = '–'
if (startDate and not startDate:match('^%d+$')) or (endDate and not endDate:match('^%d+$')) then
dash = ' – '
end
return (startDate or '') .. dash .. (endDate or '')
end
end
if type(qualifiers) == 'string' and qualifiers:find('[Pp]%d') then
qualifiers = qualifiers:upper()
else
qualifiers = nil
end
for key, snaks in pairs(statement.qualifiers) do
if not qualifiers or qualifiers:find(key, 1, true) then
if key == 'P580' then
startDate = formatSnak(snaks[1], {link = 'nem'})
elseif key == 'P582' then
endDate = formatSnak(snaks[1], {link = 'nem'})
else
for _, snak in ipairs(snaks) do
local formattedSnak = formatSnak(snak, {
link = snak.property ~= 'P102' and 'nem' or nil,
['format'] = 'geohack',
showUnit = true,
labelProperty = 'P1813' -- [[d:Property:P1813]] rövid név
})
if qualifiers then
-- order determined by the order in parameter
if orderedResult[key] then
table.insert(orderedResult[key], formattedSnak)
else
orderedResult[key] = { formattedSnak }
end
else
table.insert(result, formattedSnak)
end
end
end
end
end
if qualifiers then
for qualifier in qualifiers:gmatch('P%d+') do
if qualifier == 'P580' or qualifier == 'P582' then
local interval = getInterval()
if interval then
table.insert(result, interval)
-- prevent interval to be inserted twice (both at P580 and P582)
startDate, endDate = nil, nil
end
elseif orderedResult[qualifier] then
for _, v in ipairs(orderedResult[qualifier]) do
table.insert(result, v)
end
end
end
else
local interval = getInterval()
if interval then
table.insert(result, 1, interval)
end
end
return table.concat(result, ', ')
end
function p.formatStatement(statement, aOptions, last)
if not statement.type or statement.type ~= 'statement' then
formatError('unknown-claim-type')
end
local options = aOptions or {}
local result
if statement.mainsnak.snaktype == 'somevalue' and statement.mainsnak.datatype == 'time' and statement.qualifiers and
(statement.qualifiers.P1319 or statement.qualifiers.P1326) then
-- TODO Extract method
if statement.qualifiers.P1319 then
if statement.qualifiers.P1326 then
result = formatSnak(statement.qualifiers.P1319[1]) .. ' és ' .. formatSnak(statement.qualifiers.P1326[1]) .. ' között'
else
result = formatSnak(statement.qualifiers.P1319[1]) .. ' után'
end
else
result = formatSnak(statement.qualifiers.P1326[1]) .. ' előtt'
end
else
result = formatSnak(statement.mainsnak, options, statement)
end
--TODO reference and qualifiers
if result and result ~= '' then
if options.showQualifiers and statement.qualifiers then
local formattedQualifiers = formatQualifiers(statement, options, options.showQualifiers)
if formattedQualifiers and formattedQualifiers ~= '' then
result = result .. ' <small>(' .. formattedQualifiers .. ')</small>'
end
end
if last and options.punctuation then
result = result .. options.punctuation
end
if options.showReferences then
result = result .. formatReferences(statement.references, options)
end
end
return result
end
function p.formatStatements(frame, args, item)
if not args then
args = getArgs(frame, { removeBlanks = false })
end
--If a value if already set, use it
if args.value and args.value ~= '' then
return args.value ~= '-' and args.value or nil
end
if args.externalId == '-' then
return nil
end
if args.externalId and args.externalId ~= '' then
return formatExternalId(args, args.externalId)
end
args.entityId = args.entityId ~= '' and args.entityId or nil
args.pageTitle = args.pageTitle ~= '' and args.pageTitle or nil
args.qualProp = args.qualProp ~= '' and args.qualProp or nil
args.qualValue = args.qualValue ~= '' and args.qualValue or nil
return formatStatements(args, item)
end
--[[
Returns string true if connected Wikibase item contains property specified
by property argument, empty string otherwise.
Used by template Wikidata-f in conditional expressions.
--]]
function p.containsProperty(frame, args, item)
if not args then
args = getArgs(frame, { removeBlanks = false })
end
if not args.property then
formatError('property-param-not-provided')
end
if args.value == '-' or args.externalId == '-' then
return nil
end
if args.value then
return true
end
if args.externalId and args.externalId ~= '' then
return true
end
if not item then -- default usage from Wikidata-f template
args.entityId = args.entityId ~= '' and args.entityId or nil
args.pageTitle = args.pageTitle ~= '' and args.pageTitle or nil
local entityId = args.entityId
if not entityId then
if args.pageTitle then
entityId = mw.wikibase.getEntityIdForTitle(args.pageTitle)
else
entityId = mw.wikibase.getEntityIdForCurrentPage()
end
end
if not entityId then
return nil
end
for _, s in ipairs(mw.wikibase.getBestStatements(entityId, args.property:upper())) do
if not args.excludespecial or s.mainsnak.snaktype == 'value' then
return true
end
end
return nil
end
if not item.claims or not item.claims[args.property:upper()] then
return nil
end
if args.rank == 'all' then
return true
elseif args.rank == 'valid' then
-- if we're just searching, it doesn't matter
-- if we want all or only the better ones
args.rank = nil
end
for _, claim in ipairs(item.claims[args.property:upper()]) do
if
(args.rank and claim.rank == args.rank or not args.rank and claim.rank ~= 'deprecated') and
(not args.excludespecial or claim.mainsnak.snaktype == 'value')
then
return true
end
end
return nil
end
function p.containsPropertyWithValue(item, property, value)
if not property or not value then
return false
end
if not item or not item.claims or not item.claims[property:upper()] then
return false
end
for _, statement in ipairs(item.claims[property:upper()]) do
if statement.rank ~= 'deprecated' and statement.mainsnak.snaktype == 'value' then
local type = statement.mainsnak.datavalue.type
if type == 'wikibase-entityid' then
if 'Q' .. statement.mainsnak.datavalue.value['numeric-id'] == value then
return true
end
end
end
end
return false
end
function p.isOfType(itemId, class)
if not itemId or not class then
return false
end
local visited = {}
local function checkProperty(aItemId, property, level)
if level > 5 then
return false
end
if visited[aItemId] then
return false
end
visited[aItemId] = true
for _, s in ipairs(mw.wikibase.getBestStatements(aItemId, property)) do
if s.mainsnak.snaktype == 'value' then
local itemClass = s.mainsnak.datavalue.value.id
if itemClass == class or checkProperty(itemClass, 'P279', level + 1) then
return true
end
end
end
return false
end
return checkProperty(itemId, 'P31', 0)
end
--[[
Local functions available to other modules.
]]
p.formatters = {
formatDatavalue = formatDatavalue,
formatSnak = formatSnak,
formatSnaks = formatSnaks
}
return p