Modul:Wikidata: Porovnání verzí
m (naimportována 1 revize) |
m (ignorování neznámých hodnot u časových intervalů, dokud nebude jasné, jak to používat) |
||
| Řádek 7: | Řádek 7: | ||
local getArgs = (require 'Modul:Arguments').getArgs | local getArgs = (require 'Modul:Arguments').getArgs | ||
| + | |||
| + | local function outputBool(arg, ifexpr) | ||
| + | local map | ||
| + | if ifexpr then | ||
| + | map = { [true] = 1, [false] = 0 } | ||
| + | else | ||
| + | map = { [true] = 1, [false] = '' } | ||
| + | end | ||
| + | return map[arg] | ||
| + | end | ||
| + | |||
| + | -- todo: move to lib | ||
| + | local function augmentArgs(args, defaults, prefix) | ||
| + | local out = {} | ||
| + | prefix = prefix or '' | ||
| + | setmetatable(out, { | ||
| + | __index = function (t, key) | ||
| + | return args[prefix .. key] or defaults[key] | ||
| + | end, | ||
| + | }) | ||
| + | return out | ||
| + | end | ||
local function getEntityIdFromStatements(statements) | local function getEntityIdFromStatements(statements) | ||
| Řádek 12: | Řádek 34: | ||
if lib.IsSnakValue(statement.mainsnak) then | if lib.IsSnakValue(statement.mainsnak) then | ||
if statement.mainsnak.datavalue.type ~= 'wikibase-entityid' then | if statement.mainsnak.datavalue.type ~= 'wikibase-entityid' then | ||
| − | + | error(lib.raiseInvalidDatatype('getEntityIdFromStatements', | |
statement.mainsnak.datatype, {'wikibase-item', 'wikibase-property'})) | statement.mainsnak.datatype, {'wikibase-item', 'wikibase-property'})) | ||
end | end | ||
local Formatters = require 'Modul:Wikidata/Formatters' | local Formatters = require 'Modul:Wikidata/Formatters' | ||
| − | return Formatters.getRawValue(statement.mainsnak) | + | return Formatters.getRawValue(statement.mainsnak, {}) |
end | end | ||
| + | break | ||
end | end | ||
return nil | return nil | ||
| Řádek 111: | Řádek 134: | ||
local site = options.site or options[1] | local site = options.site or options[1] | ||
| − | local sitelink = mw.wikibase. | + | local sitelink = mw.wikibase.getSitelink(id, site) |
if not sitelink then | if not sitelink then | ||
| Řádek 128: | Řádek 151: | ||
local function formatStatementAndData(statement, options) | local function formatStatementAndData(statement, options) | ||
if not statement.type or statement.type ~= 'statement' then | if not statement.type or statement.type ~= 'statement' then | ||
| − | + | error(lib.formatError('unknown-claim-type', statement.type or '[neznámý]')) -- fixme: i18n | |
end | end | ||
local Filterers = require 'Modul:Wikidata/Filterers' | local Filterers = require 'Modul:Wikidata/Filterers' | ||
| Řádek 137: | Řádek 160: | ||
if statement.qualifiers and options.showqualifier then | if statement.qualifiers and options.showqualifier then | ||
local PropList = lib.textToTable(options.showqualifier) | local PropList = lib.textToTable(options.showqualifier) | ||
| + | -- todo: move this to a better place (config) | ||
| + | local default_options = { | ||
| + | isQualifier = true, | ||
| + | label = 'short', | ||
| + | nolink = lib.IsOptionTrue(options, 'nolink'), | ||
| + | precision = 9, | ||
| + | } | ||
for _, property in ipairs(PropList) do | for _, property in ipairs(PropList) do | ||
local property = mw.ustring.upper(property) | local property = mw.ustring.upper(property) | ||
local Values = {} | local Values = {} | ||
| − | local | + | local qualifiers_options = augmentArgs(options, default_options, 'qualifiers ') |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
if statement.qualifiers[property] then | if statement.qualifiers[property] then | ||
local Qualifiers = mw.clone(statement.qualifiers[property]) | local Qualifiers = mw.clone(statement.qualifiers[property]) | ||
| − | + | qualifiers_options.property = property | |
| − | + | if not qualifiers_options.nolink then | |
| − | Filterers.filterQualifiers(Qualifiers, | + | qualifiers_options.nolink = (Qualifiers[1].datatype == 'time') |
| + | end | ||
| + | Filterers.filterQualifiers(Qualifiers, qualifiers_options) | ||
for _, snak in ipairs(Qualifiers) do | for _, snak in ipairs(Qualifiers) do | ||
| − | + | table.insert(Values, Formatters.getFormattedValue(snak, qualifiers_options)) | |
| − | |||
| − | |||
end | end | ||
elseif property == 'TIME' then | elseif property == 'TIME' then | ||
local Data = {} | local Data = {} | ||
| − | |||
| − | |||
-- todo: factor out | -- todo: factor out | ||
for key, array in pairs(lib.props) do | for key, array in pairs(lib.props) do | ||
for _, prop in ipairs(array) do | for _, prop in ipairs(array) do | ||
for _, snak in ipairs(statement.qualifiers[prop] or {}) do | for _, snak in ipairs(statement.qualifiers[prop] or {}) do | ||
| − | Data[key] = snak | + | if lib.IsSnakValue(snak) then -- dokud nebude jasné, jak to používat |
| − | + | Data[key] = snak | |
| + | break | ||
| + | end | ||
end | end | ||
end | end | ||
end | end | ||
if Data.begin or Data.ending then | if Data.begin or Data.ending then | ||
| − | table.insert(Values, lib.formatDateRange(Data, | + | qualifiers_options.nolink = true |
| + | table.insert(Values, lib.formatDateRange(Data, qualifiers_options)) | ||
end | end | ||
end | end | ||
if #Values > 0 then | if #Values > 0 then | ||
| − | result[property] = mw.text.listToText(Values) | + | -- TODO: remove duplicates |
| + | result[property] = mw.text.listToText(Values, qualifiers_options.separator, qualifiers_options.conjunction) | ||
end | end | ||
end | end | ||
end | end | ||
if statement.references and lib.IsOptionTrue(options, 'showsource') then | if statement.references and lib.IsOptionTrue(options, 'showsource') then | ||
| + | -- todo: configure custom formatter | ||
local Module = require 'Modul:Wikidata/cite' | local Module = require 'Modul:Wikidata/cite' | ||
result.ref = Module.formatReferences(statement.references, options) -- or table of references? | result.ref = Module.formatReferences(statement.references, options) -- or table of references? | ||
| Řádek 205: | Řádek 231: | ||
end | end | ||
if #tmp > 0 then | if #tmp > 0 then | ||
| − | qualifiers = table.concat(tmp, | + | qualifiers = table.concat(tmp, i18n['qualifiers separator']) |
end | end | ||
end | end | ||
| Řádek 214: | Řádek 240: | ||
if lib.IsSnakValue(statement.mainsnak) then | if lib.IsSnakValue(statement.mainsnak) then | ||
if statement.mainsnak.datavalue.type == 'wikibase-entityid' then | if statement.mainsnak.datavalue.type == 'wikibase-entityid' then | ||
| − | entity = mw.wikibase.getEntity(Formatters.getRawValue(statement.mainsnak)) | + | entity = mw.wikibase.getEntity(Formatters.getRawValue(statement.mainsnak, {})) |
else | else | ||
| − | + | error(lib.formatError('invalid-datatype', statement.mainsnak.property, statement.mainsnak.datatype, 'wikibase-item/wikibase-property')) | |
end | end | ||
end | end | ||
| Řádek 272: | Řádek 298: | ||
end | end | ||
if #Snaks > 0 then | if #Snaks > 0 then | ||
| − | qualifiers = table.concat(Snaks, | + | qualifiers = table.concat(Snaks, i18n['qualifiers separator']) |
end | end | ||
end | end | ||
| Řádek 292: | Řádek 318: | ||
local function formatStatements(statements, options) | local function formatStatements(statements, options) | ||
local formattedStatements = {} | local formattedStatements = {} | ||
| + | local set = {} | ||
for _, statement in ipairs(statements) do | for _, statement in ipairs(statements) do | ||
local formatted = formatStatement(statement, options) | local formatted = formatStatement(statement, options) | ||
| − | + | -- TODO: maybe make optional and move elsewhere | |
| − | + | if not set[formatted] then | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
table.insert(formattedStatements, formatted) | table.insert(formattedStatements, formatted) | ||
| + | set[formatted] = true | ||
end | end | ||
end | end | ||
| Řádek 337: | Řádek 359: | ||
end | end | ||
| − | local function makeList(values, options, add_more) | + | local function makeList(values, options, add_more, link) |
| + | -- TODO: handle duplicates here | ||
if add_more then | if add_more then | ||
| − | table.insert(values, mw.ustring.format(i18n['more-on-Wikidata'], | + | local parts = mw.text.split(link, '#', true) -- b/c |
| + | table.insert(values, mw.ustring.format(i18n['more-on-Wikidata'], parts[1], parts[2] or '')) | ||
end | end | ||
| − | + | local text | |
| − | end | + | if options.list == 'ul' or options.list == 'ol' then |
| − | + | local li = {} | |
| − | + | for _, val in ipairs(values) do | |
| − | + | table.insert(li, mw.ustring.format('<li>%s</li>', val)) | |
| − | + | end | |
| − | if | + | text = mw.ustring.format('<%s class="wd">%s</%s>', options.list, table.concat(li), options.list) |
| − | + | else | |
| + | text = mw.text.listToText(values, options.separator, options.conjunction) | ||
| + | if lib.IsOptionTrue(options, 'addlink') then | ||
| + | -- TODO: data-bridge-edit-flow | ||
| + | text = mw.ustring.format('%s <sup class="wd-link">([[d:%s|e]])</sup>', text, link) | ||
end | end | ||
| − | if | + | if tostring(options.addclass) ~= 'false' then |
| − | + | text = lib.addWdClass(text) | |
end | end | ||
end | end | ||
| + | return text | ||
| + | end | ||
| − | + | local function getFormattedStatements(options) | |
| − | |||
| − | |||
options.limit = tonumber(options.limit) --TODO default? | options.limit = tonumber(options.limit) --TODO default? | ||
| − | local | + | local add_more = prepareShowMore(options) |
| − | |||
| − | |||
| − | |||
| − | |||
local id = findEntityId(options) | local id = findEntityId(options) | ||
local statements = getStatements(id, options) | local statements = getStatements(id, options) | ||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
if #statements == 0 then return nil end | if #statements == 0 then return nil end | ||
| Řádek 389: | Řádek 397: | ||
-- Format statements and concat them cleanly | -- Format statements and concat them cleanly | ||
local formattedStatements = formatStatements(statements, options) | local formattedStatements = formatStatements(statements, options) | ||
| − | + | local property = mw.ustring.upper(options.property) | |
| − | + | local link = mw.ustring.format('%s#%s', id, property) | |
| − | + | local text = makeList(formattedStatements, options, add_more, link) | |
| − | |||
| − | |||
if lib.IsOptionTrue(options, 'addcat') then | if lib.IsOptionTrue(options, 'addcat') then | ||
| − | + | text = text .. lib.category('used-property', property) | |
end | end | ||
| − | + | return text | |
| − | |||
| − | |||
| − | |||
end | end | ||
local function getRawValue(options) | local function getRawValue(options) | ||
| − | if options.rank | + | if not options.rank then |
| − | + | options.rank = 'best' | |
| − | |||
| − | |||
| − | |||
| − | |||
end | end | ||
| − | |||
for _, statement in ipairs(p.getStatements(options)) do | for _, statement in ipairs(p.getStatements(options)) do | ||
local Formatters = require 'Modul:Wikidata/Formatters' | local Formatters = require 'Modul:Wikidata/Formatters' | ||
| Řádek 421: | Řádek 419: | ||
local function getQualifiers(args) | local function getQualifiers(args) | ||
if not args.qualifier then | if not args.qualifier then | ||
| − | + | error(lib.formatError('param-not-provided', 'qualifier')) | |
| + | end | ||
| + | if not args.rank then | ||
| + | args.rank = 'best' | ||
end | end | ||
for _, statement in ipairs(p.getStatements(args)) do | for _, statement in ipairs(p.getStatements(args)) do | ||
if statement.qualifiers then | if statement.qualifiers then | ||
| + | local qualifier_args = augmentArgs(args, {}, 'qualifiers ') | ||
local qualifiers = mw.clone(statement.qualifiers[mw.ustring.upper(args.qualifier)] or {}) | local qualifiers = mw.clone(statement.qualifiers[mw.ustring.upper(args.qualifier)] or {}) | ||
local Filterers = require 'Modul:Wikidata/Filterers' | local Filterers = require 'Modul:Wikidata/Filterers' | ||
| − | Filterers.filterQualifiers(qualifiers, | + | Filterers.filterQualifiers(qualifiers, qualifier_args) |
return qualifiers | return qualifiers | ||
end | end | ||
| Řádek 436: | Řádek 438: | ||
----- API pro šablony ----- | ----- API pro šablony ----- | ||
| + | |||
| + | function p.compareStatements(frame) | ||
| + | local args = getArgs(frame, { frameOnly = true }) | ||
| + | return p._compareStatements(args) | ||
| + | end | ||
function p.dumpWikidataEntity(frame) | function p.dumpWikidataEntity(frame) | ||
| − | local args = getArgs(frame, { | + | local args = getArgs(frame, { frameOnly = true }) |
return mw.dumpObject( mw.wikibase.getEntity( args.id ) ) | return mw.dumpObject( mw.wikibase.getEntity( args.id ) ) | ||
| Řádek 444: | Řádek 451: | ||
function p.getBadges(frame) | function p.getBadges(frame) | ||
| − | local args = getArgs(frame, { | + | local args = getArgs(frame, { frameOnly = true }) |
local site = args.site | local site = args.site | ||
if not site then | if not site then | ||
| − | + | error(lib.formatError('param-not-provided', 'site')) | |
end | end | ||
local entity = findEntity(args) | local entity = findEntity(args) | ||
| Řádek 457: | Řádek 464: | ||
end | end | ||
end | end | ||
| − | return table.concat( Badges, ', ' ) | + | return table.concat(Badges, ', ') |
end | end | ||
function p.getLabel(frame) | function p.getLabel(frame) | ||
| − | local args = getArgs(frame, { | + | local args = getArgs(frame, { frameOnly = true }) |
local id = findEntityId(args) | local id = findEntityId(args) | ||
if not id then | if not id then | ||
| Řádek 472: | Řádek 479: | ||
label, lang = mw.wikibase.getLabelWithLang(id) | label, lang = mw.wikibase.getLabelWithLang(id) | ||
end | end | ||
| − | if label | + | if not label then return nil end |
| + | label = mw.text.nowiki(label) | ||
| + | if lib.IsOptionTrue(args, 'addclass') then | ||
if lang ~= i18n.lang then | if lang ~= i18n.lang then | ||
| − | return lib.addWdClass(lib.formatTextInLanguage(label | + | return lib.addWdClass(lib.formatTextInLanguage(label, lang)) |
else | else | ||
return lib.addWdClass(label) | return lib.addWdClass(label) | ||
| Řádek 483: | Řádek 492: | ||
function p.getDescription(frame) | function p.getDescription(frame) | ||
| − | local args = getArgs(frame, { | + | local args = getArgs(frame, { frameOnly = true }) |
local id = findEntityId(args) | local id = findEntityId(args) | ||
if not id then | if not id then | ||
return nil | return nil | ||
end | end | ||
| − | local lang = args.lang | + | local lang, description = args.lang |
| − | if not lang or lang == mw. | + | if not lang or lang == i18n.lang then |
| − | local | + | description, lang = mw.wikibase.getDescriptionWithLang(id) |
| − | if | + | else |
| − | description = | + | local entity = mw.wikibase.getEntity(id) |
| + | if entity then | ||
| + | description, lang = entity:getDescriptionWithLang(lang) | ||
end | end | ||
| − | |||
end | end | ||
| − | + | if not description then return nil end | |
| − | if | + | description = mw.text.nowiki(description) |
| − | + | if lib.IsOptionTrue(args, 'addclass') then | |
| − | + | if lang ~= i18n.lang then | |
| − | + | return lib.addWdClass(lib.formatTextInLanguage(description, lang)) | |
| − | + | else | |
| − | + | return lib.addWdClass(description) | |
| − | |||
| − | |||
end | end | ||
| − | |||
end | end | ||
| − | return | + | return description |
end | end | ||
function p.getAliases(frame) | function p.getAliases(frame) | ||
| − | local args = getArgs(frame, { | + | local args = getArgs(frame, { frameOnly = true }) |
| − | |||
| − | |||
| − | |||
| − | |||
local entity = findEntity(args) | local entity = findEntity(args) | ||
| − | + | local lang = args.lang or i18n.lang | |
| − | |||
| − | |||
if not entity or not entity.aliases or not entity.aliases[lang] then | if not entity or not entity.aliases or not entity.aliases[lang] then | ||
return nil | return nil | ||
| Řádek 527: | Řádek 528: | ||
args.limit = tonumber(args.limit) | args.limit = tonumber(args.limit) | ||
local add_more = prepareShowMore(args) | local add_more = prepareShowMore(args) | ||
| + | local limit = args.limit | ||
local Aliases = {} | local Aliases = {} | ||
for i, alias in ipairs(entity.aliases[lang]) do | for i, alias in ipairs(entity.aliases[lang]) do | ||
| − | + | table.insert(Aliases, mw.text.nowiki(alias.value)) | |
| − | + | if i == limit then | |
| − | + | break | |
| + | end | ||
end | end | ||
| − | add_more = handleShowMore(Aliases, | + | add_more = handleShowMore(Aliases, limit, add_more) |
| − | + | return makeList(Aliases, args, add_more, entity.id) | |
| − | |||
end | end | ||
function p.getId(frame) | function p.getId(frame) | ||
local args = getArgs(frame, { | local args = getArgs(frame, { | ||
| − | |||
frameOnly = false, | frameOnly = false, | ||
| − | parentFirst = false | + | parentOnly = false, |
| + | parentFirst = false, | ||
}) | }) | ||
| Řádek 560: | Řádek 562: | ||
function p.getSitelink(frame) | function p.getSitelink(frame) | ||
| − | return getSitelink(getArgs(frame, { | + | return getSitelink(getArgs(frame, { frameOnly = true })) |
| − | |||
| − | |||
| − | |||
end | end | ||
function p.formatStatements(frame) | function p.formatStatements(frame) | ||
| − | local args = getArgs(frame, { | + | local args = getArgs(frame, { frameOnly = true }) |
| − | + | if args.value then return args.value end -- b/c for other wikis | |
| − | + | local parent_args = getArgs(frame, { parentOnly = true }) | |
| − | |||
| − | local parent_args = getArgs(frame | ||
local add | local add | ||
if parent_args.item and not args.id then | if parent_args.item and not args.id then | ||
| Řádek 594: | Řádek 591: | ||
function p.getCount(frame) | function p.getCount(frame) | ||
| − | local args = getArgs(frame, { | + | local args = getArgs(frame, { frameOnly = true }) |
| − | |||
| − | |||
| − | |||
args.limit = nil | args.limit = nil | ||
return #p.getStatements(args) | return #p.getStatements(args) | ||
| Řádek 603: | Řádek 597: | ||
function p.getRawValue(frame) | function p.getRawValue(frame) | ||
| − | return getRawValue(getArgs(frame, { | + | return getRawValue(getArgs(frame, { frameOnly = true })) |
| − | |||
| − | |||
| − | |||
end | end | ||
function p.getQualifier(frame) | function p.getQualifier(frame) | ||
| − | local args = getArgs(frame, { | + | local args = getArgs(frame, { frameOnly = true }) |
| − | + | args.limit = tonumber(args['qualifiers limit'] or args.limit) | |
| − | |||
| − | |||
| − | args.limit = tonumber(args.limit) | ||
local add_more = prepareShowMore(args) | local add_more = prepareShowMore(args) | ||
local limit = args.limit | local limit = args.limit | ||
| + | args['qualifiers limit'] = limit | ||
args.limit = 1 | args.limit = 1 | ||
| − | |||
| − | |||
| − | |||
| − | |||
local qualifiers = getQualifiers(args) | local qualifiers = getQualifiers(args) | ||
if #qualifiers == 0 then | if #qualifiers == 0 then | ||
| Řádek 634: | Řádek 619: | ||
end | end | ||
| − | local | + | local link = '' -- TODO: we don't have statement anchor |
| − | + | -- TODO: references? | |
| + | return makeList(formattedQualifiers, args, add_more, link) | ||
end | end | ||
function p.getRawQualifier(frame) | function p.getRawQualifier(frame) | ||
| − | local args = getArgs(frame, { | + | local args = getArgs(frame, { frameOnly = true }) |
| − | |||
| − | |||
| − | |||
| − | |||
args.limit = 1 | args.limit = 1 | ||
for _, qualifier in ipairs(getQualifiers(args)) do | for _, qualifier in ipairs(getQualifiers(args)) do | ||
local Formatters = require 'Modul:Wikidata/Formatters' | local Formatters = require 'Modul:Wikidata/Formatters' | ||
| − | return Formatters.getRawValue(qualifier) | + | return Formatters.getRawValue(qualifier, args) |
end | end | ||
return nil | return nil | ||
| + | end | ||
| + | |||
| + | function p.getCurrentId() | ||
| + | return mw.wikibase.getEntityIdForCurrentPage() | ||
end | end | ||
function p.formatEntity(frame) | function p.formatEntity(frame) | ||
| − | local args = getArgs(frame, { | + | local args = getArgs(frame, { frameOnly = true }) |
| − | |||
| − | |||
| − | |||
args.id = args.id or p.getCurrentId() | args.id = args.id or p.getCurrentId() | ||
if args.id then | if args.id then | ||
| Řádek 665: | Řádek 648: | ||
end | end | ||
| − | function p. | + | function p.entityExists(frame) |
| − | + | return outputBool( | |
| − | + | mw.wikibase.entityExists(frame.args.id or frame.args[1]), | |
| − | + | lib.IsOptionTrue(frame.args, 'ifexpr')) | |
| − | + | end | |
| − | return | + | |
| + | function p.isValidEntityId(frame) | ||
| + | return outputBool( | ||
| + | mw.wikibase.isValidEntityId(frame.args.id or frame.args[1]), | ||
| + | lib.IsOptionTrue(frame.args, 'ifexpr')) | ||
end | end | ||
----- API pro moduly ----- | ----- API pro moduly ----- | ||
| − | |||
| − | |||
function p.formatStatementsFromLua(options) | function p.formatStatementsFromLua(options) | ||
| Řádek 701: | Řádek 686: | ||
function p.getRawValueFromLua(options) | function p.getRawValueFromLua(options) | ||
return getRawValue(options) | return getRawValue(options) | ||
| + | end | ||
| + | |||
| + | function p.getRawValues(options) | ||
| + | local Values = {} | ||
| + | local Formatters = require 'Modul:Wikidata/Formatters' | ||
| + | for _, st in ipairs(p.getStatements(options)) do | ||
| + | table.insert(Values, Formatters.getRawValue(st.mainsnak, options)) | ||
| + | end | ||
| + | return Values | ||
end | end | ||
| Řádek 707: | Řádek 701: | ||
function p._compareStatements(args) | function p._compareStatements(args) | ||
if not args.value then | if not args.value then | ||
| − | + | error(lib.formatError('param-not-provided', 'value')) | |
end | end | ||
local statements = p.getStatements(args) | local statements = p.getStatements(args) | ||
local compare = require 'Modul:Wikidata/compare' | local compare = require 'Modul:Wikidata/compare' | ||
return compare.compareValues(args.value, statements, args) | return compare.compareValues(args.value, statements, args) | ||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
end | end | ||
return p | return p | ||
Verze z 11. 4. 2021, 11:28
Dokumentaci tohoto modulu lze vytvořit na stránce Modul:Wikidata/Dokumentace
require 'Modul:No globals'
local p = {}
local lib = require 'Modul:Wikidata/lib'
local i18n = mw.loadData('Modul:Wikidata/i18n')
local getArgs = (require 'Modul:Arguments').getArgs
local function outputBool(arg, ifexpr)
local map
if ifexpr then
map = { [true] = 1, [false] = 0 }
else
map = { [true] = 1, [false] = '' }
end
return map[arg]
end
-- todo: move to lib
local function augmentArgs(args, defaults, prefix)
local out = {}
prefix = prefix or ''
setmetatable(out, {
__index = function (t, key)
return args[prefix .. key] or defaults[key]
end,
})
return out
end
local function getEntityIdFromStatements(statements)
for _, statement in ipairs(statements) do
if lib.IsSnakValue(statement.mainsnak) then
if statement.mainsnak.datavalue.type ~= 'wikibase-entityid' then
error(lib.raiseInvalidDatatype('getEntityIdFromStatements',
statement.mainsnak.datatype, {'wikibase-item', 'wikibase-property'}))
end
local Formatters = require 'Modul:Wikidata/Formatters'
return Formatters.getRawValue(statement.mainsnak, {})
end
break
end
return nil
end
local function getEntityIdFromEntity(entity, prop)
local prop = mw.ustring.upper(prop)
local statements = entity:getBestStatements(prop)
return getEntityIdFromStatements(statements)
end
local function getEntityIdFromId(id, prop)
local prop = mw.ustring.upper(prop)
local statements = mw.wikibase.getBestStatements(id, prop)
return getEntityIdFromStatements(statements)
end
local function getIdFromTitle(titleString, wiki)
if wiki then
return mw.wikibase.getEntityIdForTitle(titleString, wiki)
end
local title = mw.title.new(titleString)
while title do
local id = mw.wikibase.getEntityIdForTitle(title.prefixedText)
if id then
return id
end
title = title.redirectTarget
end
return nil
end
local function findEntityId(options)
local id
if options.entity and type(options.entity) == 'table' then
id = options.entity.id
end
if not id and options.page then
id = getIdFromTitle(options.page, options.wiki)
if not id then
return nil
end
end
if not id then
id = options.id or p.getCurrentId()
end
if id and options.of then
id = getEntityIdFromId(id, options.of)
end
return id
end
local function findEntity(options)
local entity
if options.entity and type(options.entity) == 'table' then
entity = options.entity
end
if not entity then
if options.id then
local id = options.id:upper()
entity = mw.wikibase.getEntity(id)
if entity and entity.id ~= id then
mw.log(id .. ' je přesměrování na ' .. entity.id)
end
else
if options.page then
local id = getIdFromTitle(options.page, options.wiki)
if id then
entity = mw.wikibase.getEntity(id)
end
else
entity = mw.wikibase.getEntity()
end
end
end
if options.of then
if entity then
local id = getEntityIdFromEntity(entity, options.of)
if id then
return mw.wikibase.getEntity(id)
end
end
return nil
end
return entity
end
local function getSitelink(options)
local id = findEntityId(options)
if not id then
return nil
end
local site = options.site or options[1]
local sitelink = mw.wikibase.getSitelink(id, site)
if not sitelink then
return nil
end
if options.pattern then
sitelink = lib.formatFromPattern(sitelink, options.pattern)
end
if lib.IsOptionTrue(options, 'addclass') then
sitelink = lib.addWdClass(sitelink)
end
return sitelink
end
local function formatStatementAndData(statement, options)
if not statement.type or statement.type ~= 'statement' then
error(lib.formatError('unknown-claim-type', statement.type or '[neznámý]')) -- fixme: i18n
end
local Filterers = require 'Modul:Wikidata/Filterers'
local Formatters = require 'Modul:Wikidata/Formatters'
local result = { Formatters.getFormattedValue(statement.mainsnak, options) }
local qualifiers
if statement.qualifiers and options.showqualifier then
local PropList = lib.textToTable(options.showqualifier)
-- todo: move this to a better place (config)
local default_options = {
isQualifier = true,
label = 'short',
nolink = lib.IsOptionTrue(options, 'nolink'),
precision = 9,
}
for _, property in ipairs(PropList) do
local property = mw.ustring.upper(property)
local Values = {}
local qualifiers_options = augmentArgs(options, default_options, 'qualifiers ')
if statement.qualifiers[property] then
local Qualifiers = mw.clone(statement.qualifiers[property])
qualifiers_options.property = property
if not qualifiers_options.nolink then
qualifiers_options.nolink = (Qualifiers[1].datatype == 'time')
end
Filterers.filterQualifiers(Qualifiers, qualifiers_options)
for _, snak in ipairs(Qualifiers) do
table.insert(Values, Formatters.getFormattedValue(snak, qualifiers_options))
end
elseif property == 'TIME' then
local Data = {}
-- todo: factor out
for key, array in pairs(lib.props) do
for _, prop in ipairs(array) do
for _, snak in ipairs(statement.qualifiers[prop] or {}) do
if lib.IsSnakValue(snak) then -- dokud nebude jasné, jak to používat
Data[key] = snak
break
end
end
end
end
if Data.begin or Data.ending then
qualifiers_options.nolink = true
table.insert(Values, lib.formatDateRange(Data, qualifiers_options))
end
end
if #Values > 0 then
-- TODO: remove duplicates
result[property] = mw.text.listToText(Values, qualifiers_options.separator, qualifiers_options.conjunction)
end
end
end
if statement.references and lib.IsOptionTrue(options, 'showsource') then
-- todo: configure custom formatter
local Module = require 'Modul:Wikidata/cite'
result.ref = Module.formatReferences(statement.references, options) -- or table of references?
end
return result
end
local function formatStatement(statement, options)
local data = formatStatementAndData(statement, options)
local result = data[1]
if options.isQualifier == true then
return result
end
local qualifiers
if statement.qualifiers and options.showqualifier then
local PropList = lib.textToTable(options.showqualifier)
local tmp = {}
for _, prop in ipairs(PropList) do
local prop = mw.ustring.upper(prop)
if data[prop] then
table.insert(tmp, data[prop])
end
end
if #tmp > 0 then
qualifiers = table.concat(tmp, i18n['qualifiers separator'])
end
end
if not qualifiers and options.showtargetdata then
local entity
local Filterers = require 'Modul:Wikidata/Filterers'
local Formatters = require 'Modul:Wikidata/Formatters'
if lib.IsSnakValue(statement.mainsnak) then
if statement.mainsnak.datavalue.type == 'wikibase-entityid' then
entity = mw.wikibase.getEntity(Formatters.getRawValue(statement.mainsnak, {}))
else
error(lib.formatError('invalid-datatype', statement.mainsnak.property, statement.mainsnak.datatype, 'wikibase-item/wikibase-property'))
end
end
if entity then
local PropList = lib.textToTable(options.showtargetdata)
local date
local rank = 'best'
if options.targetdate then
if lib.isPropertyId(options.targetdate) then
date = p.getRawValueFromLua{ entity = options.entity, property = options.targetdate }
else
date = options.targetdate
end
if date then
rank = 'valid'
end
end
local options = {
addclass = false,
autoformat = true,
date = date,
entity = entity,
isQualifier = true,
label = 'short',
nolink = true,
precision = 9,
rank = rank,
sort = {'date'},
}
local Snaks = {}
for _, property in ipairs(PropList) do
local result
if mw.ustring.lower(property) == 'time' then
local Data = {}
for key, array in pairs(lib.props) do
for _, prop in ipairs(array) do
options.property = prop
local Statements = Filterers.filterStatementsFromEntity(entity, options)
for _, statement in ipairs(Statements) do
Data[key] = statement.mainsnak
break
end
end
end
if Data.begin or Data.ending then
result = lib.formatDateRange(Data, options)
end
else
options.property = property
result = p.formatStatementsFromLua(options)
end
if result then
table.insert(Snaks, result)
end
end
if #Snaks > 0 then
qualifiers = table.concat(Snaks, i18n['qualifiers separator'])
end
end
end
if qualifiers then
if options.delimiter then
result = result .. options.delimiter .. qualifiers
else
result = result .. ' (' .. qualifiers .. ')'
end
end
if data.ref and data.ref ~= '' then
return result .. data.ref .. lib.category('references')
end
return result
end
local function formatStatements(statements, options)
local formattedStatements = {}
local set = {}
for _, statement in ipairs(statements) do
local formatted = formatStatement(statement, options)
-- TODO: maybe make optional and move elsewhere
if not set[formatted] then
table.insert(formattedStatements, formatted)
set[formatted] = true
end
end
return formattedStatements
end
local function getStatements(id, options)
if not id then
return {}
end
local statements = mw.wikibase.getAllStatements(id, options.property:upper())
local Filterers = require 'Modul:Wikidata/Filterers'
Filterers.filterStatements(statements, options)
return statements
end
local function prepareShowMore(options)
if options.limit and lib.IsOptionTrue(options, 'showmore') then
options.limit = options.limit + 1
return true
end
return false
end
local function handleShowMore(values, limit, add_more)
if add_more then
if #values == limit then
table.remove(values)
else
add_more = false
end
end
return add_more
end
local function makeList(values, options, add_more, link)
-- TODO: handle duplicates here
if add_more then
local parts = mw.text.split(link, '#', true) -- b/c
table.insert(values, mw.ustring.format(i18n['more-on-Wikidata'], parts[1], parts[2] or ''))
end
local text
if options.list == 'ul' or options.list == 'ol' then
local li = {}
for _, val in ipairs(values) do
table.insert(li, mw.ustring.format('<li>%s</li>', val))
end
text = mw.ustring.format('<%s class="wd">%s</%s>', options.list, table.concat(li), options.list)
else
text = mw.text.listToText(values, options.separator, options.conjunction)
if lib.IsOptionTrue(options, 'addlink') then
-- TODO: data-bridge-edit-flow
text = mw.ustring.format('%s <sup class="wd-link">([[d:%s|e]])</sup>', text, link)
end
if tostring(options.addclass) ~= 'false' then
text = lib.addWdClass(text)
end
end
return text
end
local function getFormattedStatements(options)
options.limit = tonumber(options.limit) --TODO default?
local add_more = prepareShowMore(options)
local id = findEntityId(options)
local statements = getStatements(id, options)
if #statements == 0 then return nil end
add_more = handleShowMore(statements, options.limit, add_more)
options.id = id
-- Format statements and concat them cleanly
local formattedStatements = formatStatements(statements, options)
local property = mw.ustring.upper(options.property)
local link = mw.ustring.format('%s#%s', id, property)
local text = makeList(formattedStatements, options, add_more, link)
if lib.IsOptionTrue(options, 'addcat') then
text = text .. lib.category('used-property', property)
end
return text
end
local function getRawValue(options)
if not options.rank then
options.rank = 'best'
end
for _, statement in ipairs(p.getStatements(options)) do
local Formatters = require 'Modul:Wikidata/Formatters'
return Formatters.getRawValue(statement.mainsnak, options)
end
return nil
end
local function getQualifiers(args)
if not args.qualifier then
error(lib.formatError('param-not-provided', 'qualifier'))
end
if not args.rank then
args.rank = 'best'
end
for _, statement in ipairs(p.getStatements(args)) do
if statement.qualifiers then
local qualifier_args = augmentArgs(args, {}, 'qualifiers ')
local qualifiers = mw.clone(statement.qualifiers[mw.ustring.upper(args.qualifier)] or {})
local Filterers = require 'Modul:Wikidata/Filterers'
Filterers.filterQualifiers(qualifiers, qualifier_args)
return qualifiers
end
return {}
end
return {}
end
----- API pro šablony -----
function p.compareStatements(frame)
local args = getArgs(frame, { frameOnly = true })
return p._compareStatements(args)
end
function p.dumpWikidataEntity(frame)
local args = getArgs(frame, { frameOnly = true })
return mw.dumpObject( mw.wikibase.getEntity( args.id ) )
end
function p.getBadges(frame)
local args = getArgs(frame, { frameOnly = true })
local site = args.site
if not site then
error(lib.formatError('param-not-provided', 'site'))
end
local entity = findEntity(args)
local Badges = {}
if entity and entity.sitelinks and entity.sitelinks[site] then
local Formatters = require 'Modul:Wikidata/Formatters'
for _, badge in ipairs(entity.sitelinks[site].badges) do
table.insert(Badges, Formatters.formatRawValue(badge, 'wikibase-entityid'))
end
end
return table.concat(Badges, ', ')
end
function p.getLabel(frame)
local args = getArgs(frame, { frameOnly = true })
local id = findEntityId(args)
if not id then
return nil
end
local lang, label = args.lang
if lang then
label = mw.wikibase.getLabelByLang(id, lang)
else
label, lang = mw.wikibase.getLabelWithLang(id)
end
if not label then return nil end
label = mw.text.nowiki(label)
if lib.IsOptionTrue(args, 'addclass') then
if lang ~= i18n.lang then
return lib.addWdClass(lib.formatTextInLanguage(label, lang))
else
return lib.addWdClass(label)
end
end
return label
end
function p.getDescription(frame)
local args = getArgs(frame, { frameOnly = true })
local id = findEntityId(args)
if not id then
return nil
end
local lang, description = args.lang
if not lang or lang == i18n.lang then
description, lang = mw.wikibase.getDescriptionWithLang(id)
else
local entity = mw.wikibase.getEntity(id)
if entity then
description, lang = entity:getDescriptionWithLang(lang)
end
end
if not description then return nil end
description = mw.text.nowiki(description)
if lib.IsOptionTrue(args, 'addclass') then
if lang ~= i18n.lang then
return lib.addWdClass(lib.formatTextInLanguage(description, lang))
else
return lib.addWdClass(description)
end
end
return description
end
function p.getAliases(frame)
local args = getArgs(frame, { frameOnly = true })
local entity = findEntity(args)
local lang = args.lang or i18n.lang
if not entity or not entity.aliases or not entity.aliases[lang] then
return nil
end
args.limit = tonumber(args.limit)
local add_more = prepareShowMore(args)
local limit = args.limit
local Aliases = {}
for i, alias in ipairs(entity.aliases[lang]) do
table.insert(Aliases, mw.text.nowiki(alias.value))
if i == limit then
break
end
end
add_more = handleShowMore(Aliases, limit, add_more)
return makeList(Aliases, args, add_more, entity.id)
end
function p.getId(frame)
local args = getArgs(frame, {
frameOnly = false,
parentOnly = false,
parentFirst = false,
})
if not args[1] then
return mw.wikibase.getEntityIdForCurrentPage()
end
for _, titleString in ipairs(args) do
local id = getIdFromTitle(titleString, args.wiki)
if id then
return id
end
end
return nil
end
function p.getSitelink(frame)
return getSitelink(getArgs(frame, { frameOnly = true }))
end
function p.formatStatements(frame)
local args = getArgs(frame, { frameOnly = true })
if args.value then return args.value end -- b/c for other wikis
local parent_args = getArgs(frame, { parentOnly = true })
local add
if parent_args.item and not args.id then
args.id = parent_args.item
add = lib.category('arbitrary-data')
end
local value = getFormattedStatements(args)
if add and value then
return value .. add
end
return value
end
function p.formatStatementsFromTemplate(frame)
local args = getArgs(frame, {
frameOnly = false,
parentOnly = false,
parentFirst = false,
})
return getFormattedStatements(args)
end
function p.getCount(frame)
local args = getArgs(frame, { frameOnly = true })
args.limit = nil
return #p.getStatements(args)
end
function p.getRawValue(frame)
return getRawValue(getArgs(frame, { frameOnly = true }))
end
function p.getQualifier(frame)
local args = getArgs(frame, { frameOnly = true })
args.limit = tonumber(args['qualifiers limit'] or args.limit)
local add_more = prepareShowMore(args)
local limit = args.limit
args['qualifiers limit'] = limit
args.limit = 1
local qualifiers = getQualifiers(args)
if #qualifiers == 0 then
return nil
end
add_more = handleShowMore(qualifiers, limit, add_more)
local Formatters = require 'Modul:Wikidata/Formatters'
local formattedQualifiers = {}
for _, qualifier in ipairs(qualifiers) do
table.insert(formattedQualifiers, Formatters.getFormattedValue(qualifier, args))
end
local link = '' -- TODO: we don't have statement anchor
-- TODO: references?
return makeList(formattedQualifiers, args, add_more, link)
end
function p.getRawQualifier(frame)
local args = getArgs(frame, { frameOnly = true })
args.limit = 1
for _, qualifier in ipairs(getQualifiers(args)) do
local Formatters = require 'Modul:Wikidata/Formatters'
return Formatters.getRawValue(qualifier, args)
end
return nil
end
function p.getCurrentId()
return mw.wikibase.getEntityIdForCurrentPage()
end
function p.formatEntity(frame)
local args = getArgs(frame, { frameOnly = true })
args.id = args.id or p.getCurrentId()
if args.id then
local Formatters = require 'Modul:Wikidata/Formatters'
return Formatters.formatRawValue(args.id, 'wikibase-entityid', args)
end
return nil
end
function p.entityExists(frame)
return outputBool(
mw.wikibase.entityExists(frame.args.id or frame.args[1]),
lib.IsOptionTrue(frame.args, 'ifexpr'))
end
function p.isValidEntityId(frame)
return outputBool(
mw.wikibase.isValidEntityId(frame.args.id or frame.args[1]),
lib.IsOptionTrue(frame.args, 'ifexpr'))
end
----- API pro moduly -----
function p.formatStatementsFromLua(options)
return getFormattedStatements(options)
end
function p.getSitelinkFromLua(options)
return getSitelink(options or {})
end
function p.getStatements(args)
local id = findEntityId(args)
return getStatements(id, args)
end
function p.getStatementsWithData(args)
local statements = p.getStatements(args)
local result = {}
for _, statement in ipairs(statements) do
table.insert(result, formatStatementAndData(statement, args))
end
return result
end
function p.getRawValueFromLua(options)
return getRawValue(options)
end
function p.getRawValues(options)
local Values = {}
local Formatters = require 'Modul:Wikidata/Formatters'
for _, st in ipairs(p.getStatements(options)) do
table.insert(Values, Formatters.getRawValue(st.mainsnak, options))
end
return Values
end
p.formatStatementsTable = formatStatements
function p._compareStatements(args)
if not args.value then
error(lib.formatError('param-not-provided', 'value'))
end
local statements = p.getStatements(args)
local compare = require 'Modul:Wikidata/compare'
return compare.compareValues(args.value, statements, args)
end
return p