„Modul:Wikibase“ – Versionsunterschied
Erscheinungsbild
KKeine Bearbeitungszusammenfassung |
KKeine Bearbeitungszusammenfassung |
||
| Zeile 188: | Zeile 188: | ||
end | end | ||
return nil, 'Nicht unterstützter Datentyp: ' .. tostring(snak.datatype or dv.type) | return nil, 'Nicht unterstützter Datentyp: ' .. tostring(snak.datatype or dv.type) | ||
end | |||
-- Q-Konfiguration: lokale Q-ID -> deutsches Label; Klartext bleibt erlaubt. | |||
-- Keine dauerhafte Zwischenspeicherung: Nutzung wird auf der Inhaltsseite erfasst. | |||
function util.resolveSmwPropertyName(setting) | |||
local name = util.trim(tostring(setting or '')) | |||
if name:match('^Q[1-9]%d*$') then | |||
return util.getClassificationName(name) | |||
end | |||
return name | |||
end | end | ||
| Zeile 193: | Zeile 203: | ||
local rows, notices, seenProperties = {}, {}, {} | local rows, notices, seenProperties = {}, {}, {} | ||
if not entityId or not entityId:match('^Q%d+$') then return rows, notices end | if not entityId or not entityId:match('^Q%d+$') then return rows, notices end | ||
for slot = 1, | for slot = 1, 6 do | ||
local property = util.trim(tostring(config['prop' .. slot] or '')) | local property = util.trim(tostring(config['prop' .. slot] or '')) | ||
if property ~= '' then | if property ~= '' then | ||
Version vom 16. Oktober 2026, 08:04 Uhr
Die Dokumentation für dieses Modul kann unter Modul:Wikibase/Doku erstellt werden
local util = {}
local function trim(s)
if type(s) ~= 'string' then return s end
return (s:gsub('^%s+', ''):gsub('%s+$', ''))
end
util.trim = trim
function util.getArgs(frame)
local args = {}
if not frame then return args end
for k, v in pairs(frame.args or {}) do
if v ~= '' and v ~= nil then args[k] = v end
end
return args
end
function util.getEntityType(id)
if type(id) ~= 'string' then return nil end
if id:match('^Q%d+$') then return 'item' end
if id:match('^P%d+$') then return 'property' end
if id:match('^L%d+$') then return 'lexeme' end
return nil
end
function util.detectEntityId(args)
local ordered = {}
local function push(v)
if v ~= nil and v ~= '' then table.insert(ordered, v) end
end
push(args.L or args.lexeme or args.l)
push(args.P or args.p)
push(args.Q or args.q)
push(args.entity or args.Entity)
push(args.id or args.ID)
push(args[1])
for _, v in ipairs(ordered) do
local s = trim(tostring(v))
if s ~= '' then
local id = s:match('^[QPL]%d+$')
if not id then id = s:match('^.-:([QPL]%d+)$') end
if id then return id end
end
end
local ok, currentId = pcall(mw.wikibase.getEntityIdForCurrentPage)
if ok and type(currentId) == 'string' and currentId:match('^[QPL]%d+$') then
return currentId
end
return nil
end
function util.getContentLangCode()
local code = 'de'
if mw.getContentLanguage then
local cl = mw.getContentLanguage()
if cl and cl.getCode then
code = cl:getCode()
end
end
return code
end
function util.getEntityLabelOrLemma(entityId)
if not entityId then return nil end
local etype = util.getEntityType(entityId)
if etype == 'lexeme' then
local ok, entity = pcall(mw.wikibase.getEntity, entityId)
if ok and type(entity) == 'table' and type(entity.lemmas) == 'table' then
local lang = util.getContentLangCode()
local l = entity.lemmas[lang]
if l and type(l) == 'table' and l.value and l.value ~= '' then
return l.value
end
for _, obj in pairs(entity.lemmas) do
if type(obj) == 'table' and obj.value and obj.value ~= '' then
return obj.value
end
end
end
end
local ok, label = pcall(mw.wikibase.getLabel, entityId)
if ok and type(label) == 'string' and label ~= '' then return label end
return entityId
end
function util.getDescription(entityId)
local ok, desc = pcall(mw.wikibase.getDescription, entityId)
if ok and type(desc) == 'string' and desc ~= '' then return desc end
return nil
end
function util.buildEntityLink(entityId, linkText, target)
linkText = trim(tostring(linkText or '')):gsub('[\r\n]+', ' ')
target = (target and tostring(target):lower()) or 'special'
if target == 'ns' then
local etype = util.getEntityType(entityId)
local prefix =
(etype == 'item' and 'Item:') or
(etype == 'property' and 'Property:') or
(etype == 'lexeme' and 'Lexeme:') or
''
local text = (linkText ~= '' and linkText) or entityId
return string.format('[[%s%s|%s]]', prefix, entityId, text)
end
-- Default: Special:EntityPage/...
local text = (linkText ~= '' and linkText) or entityId
return string.format('[[Special:EntityPage/%s|%s]]', entityId, text)
end
function util.setShortdesc(frame, text)
if not frame then return '' end
text = trim(tostring(text or '')):gsub('[\r\n]+', ' ')
if text == '' then return '' end
local ok, result = pcall(function()
return frame:callParserFunction('SHORTDESC', text)
end)
if not ok then return '' end
return result or ''
end
function util.smwAnnotate(kv)
if type(kv) ~= 'table' then return '' end
local out = {}
for prop, val in pairs(kv) do
prop = util.trim(tostring(prop or ''))
val = util.trim(tostring(val or '')):gsub('[\r\n]+', ' ')
if prop ~= '' and val ~= '' then
table.insert(out, string.format('[[%s::%s]]', prop, val))
end
end
return table.concat(out, '')
end
-- Zusätzliche Q-Aussagen: getrennt von den bisherigen Helfern für P und L.
-- Alle Entitätszugriffe erfolgen über mw.wikibase, damit der Client ihre
-- Verwendung beim Parsen der Inhaltsseite erfassen kann.
function util.getClassificationName(id)
if id:match('^L%d+$') then
local entity = mw.wikibase.getEntity(id)
local lemmas = entity and entity.lemmas or {}
if lemmas.de and lemmas.de.value and lemmas.de.value ~= '' then
return lemmas.de.value
end
local languages = {}
for language in pairs(lemmas) do languages[#languages + 1] = language end
table.sort(languages)
for _, language in ipairs(languages) do
local lemma = lemmas[language]
if lemma.value and lemma.value ~= '' then return lemma.value end
end
return id
end
local label = mw.wikibase.getLabelByLang(id, 'de')
return (label and label ~= '') and label or id
end
-- Nur verlustfrei behandelte Datentypen übernehmen. Komplexe Werte werden
-- mit Hinweis ausgelassen, statt unbemerkt Zeitpräzision/Einheiten zu verlieren.
function util.classificationValue(snak)
if not snak or snak.snaktype ~= 'value' then return nil end
local dv = snak.datavalue
if not dv then return nil, 'Aussage ohne datavalue' end
local value = dv.value
if dv.type == 'wikibase-entityid' and type(value) == 'table' then
local id = value.id
if not id and value['numeric-id'] then
local prefixes = { item = 'Q', property = 'P', lexeme = 'L' }
local prefix = prefixes[value['entity-type']]
if prefix then id = prefix .. tostring(value['numeric-id']) end
end
if id and id:match('^[QPL]%d+$') then
return util.getClassificationName(id)
end
return nil, 'Nicht unterstützter Entitätsverweis'
elseif dv.type == 'string' and type(value) == 'string' then
return value
elseif dv.type == 'monolingualtext' and type(value) == 'table' then
return value.text
end
return nil, 'Nicht unterstützter Datentyp: ' .. tostring(snak.datatype or dv.type)
end
-- Q-Konfiguration: lokale Q-ID -> deutsches Label; Klartext bleibt erlaubt.
-- Keine dauerhafte Zwischenspeicherung: Nutzung wird auf der Inhaltsseite erfasst.
function util.resolveSmwPropertyName(setting)
local name = util.trim(tostring(setting or ''))
if name:match('^Q[1-9]%d*$') then
return util.getClassificationName(name)
end
return name
end
function util.getConfiguredQStatements(entityId, config)
local rows, notices, seenProperties = {}, {}, {}
if not entityId or not entityId:match('^Q%d+$') then return rows, notices end
for slot = 1, 6 do
local property = util.trim(tostring(config['prop' .. slot] or ''))
if property ~= '' then
if not property:match('^P[1-9]%d*$') then
notices[#notices + 1] = 'Wikibase/config: prop' .. slot ..
' enthält keine gültige P-ID: ' .. property
elseif not seenProperties[property] then
seenProperties[property] = true
-- BestStatements: bevorzugte, sonst normale; keine missbilligten.
-- Auch leere Ergebnisse abfragen, damit spätere Aussagen erfasst werden.
local statements = mw.wikibase.getBestStatements(entityId, property)
local name = util.getClassificationName(property)
local seenValues = {}
for _, statement in ipairs(statements or {}) do
local value, warning = util.classificationValue(statement.mainsnak)
if warning then
notices[#notices + 1] = property .. ': ' .. warning
end
if value and value ~= '' and not seenValues[value] then
seenValues[value] = true
rows[#rows + 1] = { property = name, value = value }
end
end
end
end
end
return rows, notices
end
-- Daten aus Labels/Werten dürfen keine zusätzliche Wikitext-Syntax erzeugen.
function util.smwLiteral(value)
return mw.text.nowiki(tostring(value):gsub('[\r\n]+', ' '))
end
function util.smwAnnotateRows(rows)
local out = {}
for _, row in ipairs(rows) do
-- :: ist die SMW-Trennsyntax; in einem Attributnamen nicht zulassen.
if row.property:find('::', 1, true) then
error('Wikibase: P-Label enthält die SMW-Trennsyntax "::": ' .. row.property)
end
out[#out + 1] = '[[' .. util.smwLiteral(row.property) .. '::' ..
util.smwLiteral(row.value) .. '| ]]'
end
return table.concat(out)
end
return util