Zum Inhalt springen

„Modul:WikibaseLink“ – Versionsunterschied

aus AufEinWort, der freien Forschung
KKeine Bearbeitungszusammenfassung
KKeine Bearbeitungszusammenfassung
Zeile 1: Zeile 1:
local p = {}
local p = {}


-- Hilfsfunktion: interner Link auf eine Entität (Q/L/…)
-- === KONFIG ===
local P_ITEM2LEX = 'P9'  -- Item (Q) -> Lexem (L)  „hat Wort“
local P_LEX2ITEM = 'P8'  -- Lexem (L) -> Item (Q)  „hat Eintrag“
local NS_CATEGORY_ID = 14  -- Einordnung aliasiert Kategorie (numerisch 14)
 
-- == Hilfsfunktionen ==
local function entityLink(id, label)
local function entityLink(id, label)
if not id then return nil end
  if not id then return nil end
label = label or id
  return string.format('[[Special:EntityPage/%s|%s]]', id, label or id)
return string.format('[[Special:EntityPage/%s|%s]]', id, label)
end
 
local function isQ(id) return type(id)=='string' and id:match('^Q%d+$') end
local function isL(id) return type(id)=='string' and id:match('^L%d+$') end
 
local function getCurrentTitleParts()
  local t = mw.title.getCurrentTitle()
  return {
    nsId = t.namespace,
    nsText = t.nsText,          -- z. B. "Einordnung"
    text = t.text,              -- Seitentitel ohne Präfix (z. B. "Dingwort")
    prefixed = t.prefixedText,  -- mit Präfix
  }
end
end


-- 1) Q-Link über Sitelink (funktioniert im Content-Namensraum)
-- Beste Statements einer Property (vom Item)
function p.itemLink(frame)
local function getBestValues(qid, pid)
local id = mw.wikibase.getEntityIdForCurrentPage()
  if not (qid and isQ(qid) and pid) then return {} end
if not id or id:sub(1,1) ~= 'Q' then
  local vals = mw.wikibase.getBestStatements(qid, pid) or {}
return ''
  local out = {}
end
  for _, s in ipairs(vals) do
return entityLink(id, 'Eintrag: ' .. id)
    local snak = s.mainsnak
    if snak and snak.datavalue and snak.datavalue.value then
      local v = snak.datavalue.value
      if type(v) == 'table' and v['id'] then
        table.insert(out, v.id)              -- Wikibase-EntityId (für entity-typed props)
      else
        table.insert(out, tostring(v))       -- sonst String/Identifier
      end
    end
  end
  return out
end
end


-- 2) L-Link: explizit oder via Heuristik (Label=Seitentitel)
-- Q im aktuellen Kontext ermitteln:
-- Nutzung: {{#invoke:WikibaseLink|lexemeLink}} oder mit Vorgabe {{#invoke:WikibaseLink|lexemeLink|L= L2}}
-- 1) Direkter Sitelink (auf Artikelseiten etc.)
function p.lexemeLink(frame)
-- 2) Auf Einordnung:-Seiten: versuche Sitelink für den zugrunde liegenden Artikelnamen
local args = frame and frame.args or {}
-- 3) Fallback: exakte Labelsuche (de)
local lexId = args.L or args.lexeme or args[1]
local function resolveQForContext()
  local parts = getCurrentTitleParts()
 
  -- 1) Direkter Sitelink (nur wenn aktuelle Seite Sitelink-Ziel ist)
  local q = mw.wikibase.getEntityIdForCurrentPage()
  if isQ(q) then return q end
 
  -- 2) Kategorie/Einordnung → nutze Artikeltitel ohne Präfix
  if parts.nsId == NS_CATEGORY_ID and parts.text and parts.text ~= '' then
    local q2 = mw.wikibase.getEntityIdForTitle(parts.text)
    if isQ(q2) then return q2 end
  end


-- A) explizit übergeben
  -- 3) Fallback exakte Labelsuche in de (nur wenn ein klarer Kandidat)
if lexId and tostring(lexId):match('^L%d+$') then
  local title = parts.text or parts.prefixed
return entityLink(lexId, 'Wort: ' .. lexId)
  if not title or title == '' then return nil end
end
  local ok, results = pcall(mw.wikibase.searchEntities, title, 'de')
  if ok and type(results) == 'table' then
    local candidate
    for _, r in ipairs(results) do
      if r and r.id and isQ(r.id) and r.display and r.display.label
        and r.display.label.value == title then
        if candidate then
          candidate = nil; break  -- Mehrdeutig → kein eindeutiger Treffer
        end
        candidate = r.id
      end
    end
    if isQ(candidate) then return candidate end
  end
  return nil
end


-- B) heuristisch: per Suche nach dem Seitentitel (de)
-- L im aktuellen Kontext ermitteln:
local title = mw.title.getCurrentTitle().prefixedText
-- (a) expliziter Parameter |L=, sonst
-- Suche
-- (b) über Item->Lexem (P_ITEM2LEX),
local ok, results = pcall(mw.wikibase.searchEntities, title, 'de')
-- (c) Fallback exakte Labelsuche (de)
if not ok or type(results) ~= 'table' then
local function resolveLsForContext(frame, qForContext)
return ''
  -- (a) Override
end
  local args = frame and frame.args or {}
  local lexArg = args.L or args.lexeme or args[1]
  if lexArg and isL(tostring(lexArg)) then
    return { tostring(lexArg) }
  end


-- Filter: nur exakte Label-Treffer und nur Lexeme (IDs beginnen mit L)
  -- (b) über Item-Property
local candidates = {}
  if isQ(qForContext) then
for _, r in ipairs(results) do
    local ls = getBestValues(qForContext, P_ITEM2LEX)
if type(r) == 'table' and r.id and r.id:match('^L%d+$') then
    local out = {}
-- Exakt gleiches Label in de?
    for _, id in ipairs(ls) do
if r.display and r.display.label and r.display.label.value == title then
      if isL(id) then table.insert(out, id) end
table.insert(candidates, r.id)
    end
end
    if #out > 0 then return out end
end
  end
end


if #candidates == 1 then
  -- (c) Fallback exakte Labelsuche
return entityLink(candidates[1], 'Lexem: ' .. candidates[1])
  local parts = getCurrentTitleParts()
else
  local title = parts.text or parts.prefixed
-- 0 oder >1 exakte Kandidaten -> kein eindeutiger L-Link
  if not title or title == '' then return {} end
return ''
  local ok, results = pcall(mw.wikibase.searchEntities, title, 'de')
end
  if ok and type(results) == 'table' then
    local out = {}
    for _, r in ipairs(results) do
      if r and isL(r.id) and r.display and r.display.label
        and r.display.label.value == title then
        table.insert(out, r.id)
      end
    end
    return out
  end
  return {}
end
end


-- 3) Kombi: zeig Q und L, oder „kein WikibaseLink“
-- === Öffentliche Ausgaben ===
-- Nutzung: {{#invoke:WikibaseLink|both}}  oder  {{#invoke:WikibaseLink|both|L=L2}}
 
function p.both(frame)
function p.itemLink(frame)
local q = p.itemLink(frame)
  local q = resolveQForContext()
local l = p.lexemeLink(frame)
  if not isQ(q) then return '' end
  return entityLink(q, 'Eintrag: ' .. q)
end


if (q == '' or q == nil) and (l == '' or l == nil) then
function p.lexemeLink(frame)
return 'Link fehlt'
  local q = resolveQForContext() -- ermöglicht (b)
end
  local ls = resolveLsForContext(frame, q)
  if not ls or #ls == 0 then return '' end
  -- mehrere Lexeme ggf. joinen
  local links = {}
  for _, lid in ipairs(ls) do
    table.insert(links, entityLink(lid, 'Wortlaut: ' .. lid))
  end
  return table.concat(links, ' · ')
end


if q ~= '' and l ~= '' then
function p.both(frame)
return q .. ' · ' .. l
  local qOut = p.itemLink(frame)
elseif q ~= '' then
  local lOut = p.lexemeLink(frame)
return q
  if (qOut == '' or not qOut) and (lOut == '' or not lOut) then
else
    return 'kein WikibaseLink'
return l
  elseif qOut ~= '' and lOut ~= '' then
end
    return qOut .. ' · ' .. lOut
  else
    return (qOut ~= '' and qOut) or lOut
  end
end
end


return p
return p

Version vom 29. Oktober 2025, 07:15 Uhr

Vorlagenprogrammierung Diskussionen Lua Unterseiten
Modul Deutsch

Modul: Dokumentation

Diese Seite enthält Code in der Programmiersprache Lua. Einbindungszahl Cirrus


local p = {}

-- === KONFIG ===
local P_ITEM2LEX = 'P9'  -- Item (Q) -> Lexem (L)  „hat Wort“
local P_LEX2ITEM = 'P8'  -- Lexem (L) -> Item (Q)  „hat Eintrag“
local NS_CATEGORY_ID = 14  -- Einordnung aliasiert Kategorie (numerisch 14)

-- == Hilfsfunktionen ==
local function entityLink(id, label)
  if not id then return nil end
  return string.format('[[Special:EntityPage/%s|%s]]', id, label or id)
end

local function isQ(id) return type(id)=='string' and id:match('^Q%d+$') end
local function isL(id) return type(id)=='string' and id:match('^L%d+$') end

local function getCurrentTitleParts()
  local t = mw.title.getCurrentTitle()
  return {
    nsId = t.namespace,
    nsText = t.nsText,           -- z. B. "Einordnung"
    text = t.text,               -- Seitentitel ohne Präfix (z. B. "Dingwort")
    prefixed = t.prefixedText,   -- mit Präfix
  }
end

-- Beste Statements einer Property (vom Item)
local function getBestValues(qid, pid)
  if not (qid and isQ(qid) and pid) then return {} end
  local vals = mw.wikibase.getBestStatements(qid, pid) or {}
  local out = {}
  for _, s in ipairs(vals) do
    local snak = s.mainsnak
    if snak and snak.datavalue and snak.datavalue.value then
      local v = snak.datavalue.value
      if type(v) == 'table' and v['id'] then
        table.insert(out, v.id)              -- Wikibase-EntityId (für entity-typed props)
      else
        table.insert(out, tostring(v))       -- sonst String/Identifier
      end
    end
  end
  return out
end

-- Q im aktuellen Kontext ermitteln:
-- 1) Direkter Sitelink (auf Artikelseiten etc.)
-- 2) Auf Einordnung:-Seiten: versuche Sitelink für den zugrunde liegenden Artikelnamen
-- 3) Fallback: exakte Labelsuche (de)
local function resolveQForContext()
  local parts = getCurrentTitleParts()

  -- 1) Direkter Sitelink (nur wenn aktuelle Seite Sitelink-Ziel ist)
  local q = mw.wikibase.getEntityIdForCurrentPage()
  if isQ(q) then return q end

  -- 2) Kategorie/Einordnung → nutze Artikeltitel ohne Präfix
  if parts.nsId == NS_CATEGORY_ID and parts.text and parts.text ~= '' then
    local q2 = mw.wikibase.getEntityIdForTitle(parts.text)
    if isQ(q2) then return q2 end
  end

  -- 3) Fallback exakte Labelsuche in de (nur wenn ein klarer Kandidat)
  local title = parts.text or parts.prefixed
  if not title or title == '' then return nil end
  local ok, results = pcall(mw.wikibase.searchEntities, title, 'de')
  if ok and type(results) == 'table' then
    local candidate
    for _, r in ipairs(results) do
      if r and r.id and isQ(r.id) and r.display and r.display.label
         and r.display.label.value == title then
        if candidate then
          candidate = nil; break  -- Mehrdeutig → kein eindeutiger Treffer
        end
        candidate = r.id
      end
    end
    if isQ(candidate) then return candidate end
  end
  return nil
end

-- L im aktuellen Kontext ermitteln:
-- (a) expliziter Parameter |L=, sonst
-- (b) über Item->Lexem (P_ITEM2LEX),
-- (c) Fallback exakte Labelsuche (de)
local function resolveLsForContext(frame, qForContext)
  -- (a) Override
  local args = frame and frame.args or {}
  local lexArg = args.L or args.lexeme or args[1]
  if lexArg and isL(tostring(lexArg)) then
    return { tostring(lexArg) }
  end

  -- (b) über Item-Property
  if isQ(qForContext) then
    local ls = getBestValues(qForContext, P_ITEM2LEX)
    local out = {}
    for _, id in ipairs(ls) do
      if isL(id) then table.insert(out, id) end
    end
    if #out > 0 then return out end
  end

  -- (c) Fallback exakte Labelsuche
  local parts = getCurrentTitleParts()
  local title = parts.text or parts.prefixed
  if not title or title == '' then return {} end
  local ok, results = pcall(mw.wikibase.searchEntities, title, 'de')
  if ok and type(results) == 'table' then
    local out = {}
    for _, r in ipairs(results) do
      if r and isL(r.id) and r.display and r.display.label
         and r.display.label.value == title then
        table.insert(out, r.id)
      end
    end
    return out
  end
  return {}
end

-- === Öffentliche Ausgaben ===

function p.itemLink(frame)
  local q = resolveQForContext()
  if not isQ(q) then return '' end
  return entityLink(q, 'Eintrag: ' .. q)
end

function p.lexemeLink(frame)
  local q = resolveQForContext() -- ermöglicht (b)
  local ls = resolveLsForContext(frame, q)
  if not ls or #ls == 0 then return '' end
  -- mehrere Lexeme ggf. joinen
  local links = {}
  for _, lid in ipairs(ls) do
    table.insert(links, entityLink(lid, 'Wortlaut: ' .. lid))
  end
  return table.concat(links, ' · ')
end

function p.both(frame)
  local qOut = p.itemLink(frame)
  local lOut = p.lexemeLink(frame)
  if (qOut == '' or not qOut) and (lOut == '' or not lOut) then
    return 'kein WikibaseLink'
  elseif qOut ~= '' and lOut ~= '' then
    return qOut .. ' · ' .. lOut
  else
    return (qOut ~= '' and qOut) or lOut
  end
end

return p