Zum Inhalt springen

„Modul:WikibaseLink“ – Versionsunterschied

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


-- === KONFIG ===
------------------------------------------------------------------
local P_ITEM2LEX = 'P9'  -- Item (Q) -> Lexem (L) „hat Wort“
-- Modul:WikibaseLink – neue Fassung
local P_LEX2ITEM = 'P8'  -- Lexem (L) -> Item (Q)  „hat Eintrag“
-- Ziel:
local NS_CATEGORY_ID = 14  -- Einordnung aliasiert Kategorie (numerisch 14)
-- 1) Links zu Q / P / L ausgeben (Special:EntityPage/...)
-- 2) Für P und L passende Kurzbeschreibung ermitteln
--    - P: Wikibase-Beschreibung
--    - L: lexikalische Kategorie (Label)
-- 3) OPTIONAL: Diese Kurzbeschreibung als SHORTDESC ausgeben,
--    so dass sie als Such-Untertitel verwendet werden kann.
--
-- Nutzung (Vorschlag für Vorlage "WikibaseLink"):
--  {{#invoke:WikibaseLink|link|entity=Q123}}
--  {{#invoke:WikibaseLink|link|P=P31}}
--  {{#invoke:WikibaseLink|link|L=L1}}
--  {{#invoke:WikibaseLink|shortdesc|P=P31|mode=P}}
--  {{#invoke:WikibaseLink|shortdesc|L=L1|mode=L}}
--  {{#invoke:WikibaseLink|linkAndShortdesc|P=P31|mode=P}}
--
-- Parameter (alle Funktionen):
--   |entity=  Q123 / P31 / L1 (allgemein)
--  |Q=      explizit Item
--  |P=       explizit Property
--   |L=      explizit Lexem
--  |mode=    'auto' (Standard) / 'Q' / 'P' / 'L'
--             bestimmt, ob SHORTDESC erzeugt wird und wie.
--  |label=   optionaler Linktext statt Wikibase-Label
--
-- Fallback:
--  Wenn keine Entity per Parameter angegeben ist, versucht
--   das Modul mw.wikibase.getEntityIdForCurrentPage().
------------------------------------------------------------------


-- == Hilfsfunktionen ==
-- Hilfsfunktion: Trim
local function entityLink(id, label)
local function trim(s)
   if not id then return nil end
   if type(s) ~= 'string' then
   return string.format('[[Special:EntityPage/%s|%s]]', id, label or id)
    return s
  end
   return (s:gsub('^%s+', ''):gsub('%s+$', ''))
end
end


local function isQ(id) return type(id)=='string' and id:match('^Q%d+$') end
-- Hilfsfunktion: Argumente aus frame + Parent zusammenführen
local function isL(id) return type(id)=='string' and id:match('^L%d+$') end
local function getArgs(frame)
  local args = {}
  if not frame then
    return args
  end


local function getCurrentTitleParts()
   local parent = frame:getParent()
   local t = mw.title.getCurrentTitle()
   if parent and parent.args then
  return {
    for k, v in pairs(parent.args) do
    nsId = t.namespace,
       if v ~= '' and v ~= nil then
    nsText = t.nsText,          -- z. B. "Einordnung"
         args[k] = v
    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
     end
   end
   end
  return out
end


-- Q im aktuellen Kontext ermitteln:
  for k, v in pairs(frame.args) do
-- 1) Direkter Sitelink (auf Artikelseiten etc.)
    if v ~= '' and v ~= nil then
-- 2) Auf Einordnung:-Seiten: versuche Sitelink für den zugrunde liegenden Artikelnamen
      args[k] = v
-- 3) Fallback: exakte Labelsuche (de)
    end
local function resolveQForContext()
   end
   local parts = getCurrentTitleParts()


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


  -- 2) Kategorie/Einordnung → nutze Artikeltitel ohne Präfix
-- Entity-Typ bestimmen
   if parts.nsId == NS_CATEGORY_ID and parts.text and parts.text ~= '' then
local function getEntityType(id)
     local q2 = mw.wikibase.getEntityIdForTitle(parts.text)
   if type(id) ~= 'string' then
     if isQ(q2) then return q2 end
    return nil
  end
  if id:match('^Q%d+$') then
     return 'item'    -- Q
  elseif id:match('^P%d+$') then
     return 'property' -- P
  elseif id:match('^L%d+$') then
    return 'lexeme'  -- L
   end
   end
  return nil
end
-- Entity-ID aus den Argumenten (oder Kontext) ermitteln
local function detectEntityId(args)
  local candidates = {
    args.entity or args.Entity,
    args.id or args.ID,
    args.Q or args.q,
    args.P or args.p,
    args.L or args.lexeme or args.l,
    args[1],
  }


   -- 3) Fallback exakte Labelsuche in de (nur wenn ein klarer Kandidat)
   for _, v in ipairs(candidates) do
  local title = parts.text or parts.prefixed
    if v ~= nil and v ~= '' then
  if not title or title == '' then return nil end
      local s = trim(tostring(v))
  local ok, results = pcall(mw.wikibase.searchEntities, title, 'de')
      if s ~= '' and s:match('^[QPL]%d+$') then
  if ok and type(results) == 'table' then
         return s
    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
     end
     end
    if isQ(candidate) then return candidate end
   end
   end
  -- Fallback: Entity zur aktuellen Seite (z. B. Q bei Sitelink
  local ok, currentId = pcall(mw.wikibase.getEntityIdForCurrentPage)
  if ok and type(currentId) == 'string' and currentId:match('^[QPL]%d+$') then
    return currentId
  end
   return nil
   return nil
end
end


-- L im aktuellen Kontext ermitteln:
-- Link auf eine Entity bauen (mit optionalem Label)
-- (a) expliziter Parameter |L=, sonst
local function buildEntityLink(entityId, labelOverride)
-- (b) über Item->Lexem (P_ITEM2LEX),
   if not entityId then
-- (c) Fallback exakte Labelsuche (de)
     return ''
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
   end


   -- (b) über Item-Property
   local label = labelOverride
   if isQ(qForContext) then
   if not label or label == '' then
     local ls = getBestValues(qForContext, P_ITEM2LEX)
     local ok, fetched = pcall(mw.wikibase.getLabel, entityId)
     local out = {}
     if ok and fetched and fetched ~= '' then
     for _, id in ipairs(ls) do
      label = fetched
       if isL(id) then table.insert(out, id) end
     else
       label = entityId
     end
     end
    if #out > 0 then return out end
   end
   end


   -- (c) Fallback exakte Labelsuche
   return string.format('[[Special:EntityPage/%s|%s]]', entityId, label)
   local parts = getCurrentTitleParts()
end
   local title = parts.text or parts.prefixed
 
   if not title or title == '' then return {} end
-- Kurzbeschreibung für eine Entity bestimmen
   local ok, results = pcall(mw.wikibase.searchEntities, title, 'de')
-- mode:
  if ok and type(results) == 'table' then
--  'auto' / nil ->
     local out = {}
--      Q (item)      → keine SHORTDESC (Q-Seiten haben eigene Brücke)
     for _, r in ipairs(results) do
--      P (property)  → Wikibase-Beschreibung
       if r and isL(r.id) and r.display and r.display.label
--      L (lexeme)    → Label der lexikalischen Kategorie
        and r.display.label.value == title then
--   'Q' / 'item'      → keine SHORTDESC
        table.insert(out, r.id)
--  'P' / 'property'  → Wikibase-Beschreibung
       end
--  'L' / 'lexeme'    → Label der lexikalischen Kategorie
local function buildShortdescText(entityId, mode)
  if not entityId then
    return nil
  end
 
   local etype = getEntityType(entityId)
   if not etype then
    return nil
  end
 
  mode = mode and tostring(mode):lower() or 'auto'
 
  if mode == 'auto' then
    if etype == 'item' then
      -- Q-Entities: keine SHORTDESC, Beschreibung kommt über Wikibase-Sitelink
      return nil
    elseif etype == 'property' then
      mode = 'p'
    elseif etype == 'lexeme' then
      mode = 'l'
    end
  end
 
  if mode == 'q' or mode == 'item' then
    -- bewusst leer: Q-Beschreibungen kommen zentral
    return nil
 
   elseif mode == 'p' or mode == 'property' then
    local ok, desc = pcall(mw.wikibase.getDescription, entityId)
    if ok and type(desc) == 'string' and desc ~= '' then
      return desc
    end
    return nil
 
  elseif mode == 'l' or mode == 'lexeme' then
     local ok, entity = pcall(mw.wikibase.getEntity, entityId)
     if not ok or type(entity) ~= 'table' then
       return nil
    end
 
    local lc = entity.lexicalCategory
    if type(lc) == 'table' then
      lc = lc.id or lc.value
    end
 
    if type(lc) ~= 'string' or lc == '' then
      return nil
    end
 
    local okLabel, label = pcall(mw.wikibase.getLabel, lc)
    if okLabel and type(label) == 'string' and label ~= '' then
      return label
    else
       return lc
     end
     end
    return out
   end
   end
   return {}
 
   return nil
end
end


-- === Öffentliche Ausgaben ===
------------------------------------------------------------------
-- Öffentliche Funktionen
------------------------------------------------------------------


function p.itemLink(frame)
-- 1) Nur Link ausgeben
   local q = resolveQForContext()
function p.link(frame)
   if not isQ(q) then return '' end
  local args = getArgs(frame)
   return entityLink(q, '' .. q)
   local entityId = detectEntityId(args)
   if not entityId then
    return ''
  end
  local label = args.label or args.text
   return buildEntityLink(entityId, label)
end
end


function p.lexemeLink(frame)
-- 2) Nur SHORTDESC ausgeben (falls sinnvoll)
   local q = resolveQForContext() -- ermöglicht (b)
function p.shortdesc(frame)
   local ls = resolveLsForContext(frame, q)
   local args = getArgs(frame)
   if not ls or #ls == 0 then return '' end
   local entityId = detectEntityId(args)
   -- mehrere Lexeme ggf. joinen
   if not entityId then
   local links = {}
    return ''
   for _, lid in ipairs(ls) do
  end
     table.insert(links, entityLink(lid, '' .. lid))
 
   local mode = args.mode or args.typ or args.type
   local text = buildShortdescText(entityId, mode)
   if not text or text == '' then
     return ''
   end
   end
   return table.concat(links, ' · ')
 
  text = trim(text):gsub('\n', ' ')
   return string.format('{{SHORTDESC:%s}}', text)
end
end


function p.both(frame)
-- 3) Link + SHORTDESC kombinieren
   local qOut = p.itemLink(frame)
function p.linkAndShortdesc(frame)
   local lOut = p.lexemeLink(frame)
   local args = getArgs(frame)
   if (qOut == '' or not qOut) and (lOut == '' or not lOut) then
   local entityId = detectEntityId(args)
    return 'kein WikibaseLink'
   if not entityId then
   elseif qOut ~= '' and lOut ~= '' then
    return ''
     return qOut .. ' · ' .. lOut
  end
  else
 
    return (qOut ~= '' and qOut) or lOut
  local mode = args.mode or args.typ or args.type
  local label = args.label or args.text
 
  local short = buildShortdescText(entityId, mode)
  local link  = buildEntityLink(entityId, label)
 
   local out = {}
  if short and short ~= '' then
     short = trim(short):gsub('\n', ' ')
    table.insert(out, string.format('{{SHORTDESC:%s}}', short))
   end
   end
  if link and link ~= '' then
    table.insert(out, link)
  end
  return table.concat(out, '\n')
end
end


return p
return p

Version vom 11. Dezember 2025, 15:21 Uhr

Vorlagenprogrammierung Diskussionen Lua Unterseiten
Modul Deutsch

Modul: Dokumentation

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


local p = {}

------------------------------------------------------------------
-- Modul:WikibaseLink – neue Fassung
-- Ziel:
-- 1) Links zu Q / P / L ausgeben (Special:EntityPage/...)
-- 2) Für P und L passende Kurzbeschreibung ermitteln
--    - P: Wikibase-Beschreibung
--    - L: lexikalische Kategorie (Label)
-- 3) OPTIONAL: Diese Kurzbeschreibung als SHORTDESC ausgeben,
--    so dass sie als Such-Untertitel verwendet werden kann.
--
-- Nutzung (Vorschlag für Vorlage "WikibaseLink"):
--   {{#invoke:WikibaseLink|link|entity=Q123}}
--   {{#invoke:WikibaseLink|link|P=P31}}
--   {{#invoke:WikibaseLink|link|L=L1}}
--   {{#invoke:WikibaseLink|shortdesc|P=P31|mode=P}}
--   {{#invoke:WikibaseLink|shortdesc|L=L1|mode=L}}
--   {{#invoke:WikibaseLink|linkAndShortdesc|P=P31|mode=P}}
--
-- Parameter (alle Funktionen):
--   |entity=  Q123 / P31 / L1 (allgemein)
--   |Q=       explizit Item
--   |P=       explizit Property
--   |L=       explizit Lexem
--   |mode=    'auto' (Standard) / 'Q' / 'P' / 'L'
--             bestimmt, ob SHORTDESC erzeugt wird und wie.
--   |label=   optionaler Linktext statt Wikibase-Label
--
-- Fallback:
--   Wenn keine Entity per Parameter angegeben ist, versucht
--   das Modul mw.wikibase.getEntityIdForCurrentPage().
------------------------------------------------------------------

-- Hilfsfunktion: Trim
local function trim(s)
  if type(s) ~= 'string' then
    return s
  end
  return (s:gsub('^%s+', ''):gsub('%s+$', ''))
end

-- Hilfsfunktion: Argumente aus frame + Parent zusammenführen
local function getArgs(frame)
  local args = {}
  if not frame then
    return args
  end

  local parent = frame:getParent()
  if parent and parent.args then
    for k, v in pairs(parent.args) do
      if v ~= '' and v ~= nil then
        args[k] = v
      end
    end
  end

  for k, v in pairs(frame.args) do
    if v ~= '' and v ~= nil then
      args[k] = v
    end
  end

  return args
end

-- Entity-Typ bestimmen
local function getEntityType(id)
  if type(id) ~= 'string' then
    return nil
  end
  if id:match('^Q%d+$') then
    return 'item'    -- Q
  elseif id:match('^P%d+$') then
    return 'property' -- P
  elseif id:match('^L%d+$') then
    return 'lexeme'  -- L
  end
  return nil
end

-- Entity-ID aus den Argumenten (oder Kontext) ermitteln
local function detectEntityId(args)
  local candidates = {
    args.entity or args.Entity,
    args.id or args.ID,
    args.Q or args.q,
    args.P or args.p,
    args.L or args.lexeme or args.l,
    args[1],
  }

  for _, v in ipairs(candidates) do
    if v ~= nil and v ~= '' then
      local s = trim(tostring(v))
      if s ~= '' and s:match('^[QPL]%d+$') then
        return s
      end
    end
  end

  -- Fallback: Entity zur aktuellen Seite (z. B. Q bei Sitelink
  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

-- Link auf eine Entity bauen (mit optionalem Label)
local function buildEntityLink(entityId, labelOverride)
  if not entityId then
    return ''
  end

  local label = labelOverride
  if not label or label == '' then
    local ok, fetched = pcall(mw.wikibase.getLabel, entityId)
    if ok and fetched and fetched ~= '' then
      label = fetched
    else
      label = entityId
    end
  end

  return string.format('[[Special:EntityPage/%s|%s]]', entityId, label)
end

-- Kurzbeschreibung für eine Entity bestimmen
-- mode:
--   'auto' / nil ->
--       Q (item)      → keine SHORTDESC (Q-Seiten haben eigene Brücke)
--       P (property)  → Wikibase-Beschreibung
--       L (lexeme)    → Label der lexikalischen Kategorie
--   'Q' / 'item'      → keine SHORTDESC
--   'P' / 'property'  → Wikibase-Beschreibung
--   'L' / 'lexeme'    → Label der lexikalischen Kategorie
local function buildShortdescText(entityId, mode)
  if not entityId then
    return nil
  end

  local etype = getEntityType(entityId)
  if not etype then
    return nil
  end

  mode = mode and tostring(mode):lower() or 'auto'

  if mode == 'auto' then
    if etype == 'item' then
      -- Q-Entities: keine SHORTDESC, Beschreibung kommt über Wikibase-Sitelink
      return nil
    elseif etype == 'property' then
      mode = 'p'
    elseif etype == 'lexeme' then
      mode = 'l'
    end
  end

  if mode == 'q' or mode == 'item' then
    -- bewusst leer: Q-Beschreibungen kommen zentral
    return nil

  elseif mode == 'p' or mode == 'property' then
    local ok, desc = pcall(mw.wikibase.getDescription, entityId)
    if ok and type(desc) == 'string' and desc ~= '' then
      return desc
    end
    return nil

  elseif mode == 'l' or mode == 'lexeme' then
    local ok, entity = pcall(mw.wikibase.getEntity, entityId)
    if not ok or type(entity) ~= 'table' then
      return nil
    end

    local lc = entity.lexicalCategory
    if type(lc) == 'table' then
      lc = lc.id or lc.value
    end

    if type(lc) ~= 'string' or lc == '' then
      return nil
    end

    local okLabel, label = pcall(mw.wikibase.getLabel, lc)
    if okLabel and type(label) == 'string' and label ~= '' then
      return label
    else
      return lc
    end
  end

  return nil
end

------------------------------------------------------------------
-- Öffentliche Funktionen
------------------------------------------------------------------

-- 1) Nur Link ausgeben
function p.link(frame)
  local args = getArgs(frame)
  local entityId = detectEntityId(args)
  if not entityId then
    return ''
  end
  local label = args.label or args.text
  return buildEntityLink(entityId, label)
end

-- 2) Nur SHORTDESC ausgeben (falls sinnvoll)
function p.shortdesc(frame)
  local args = getArgs(frame)
  local entityId = detectEntityId(args)
  if not entityId then
    return ''
  end

  local mode = args.mode or args.typ or args.type
  local text = buildShortdescText(entityId, mode)
  if not text or text == '' then
    return ''
  end

  text = trim(text):gsub('\n', ' ')
  return string.format('{{SHORTDESC:%s}}', text)
end

-- 3) Link + SHORTDESC kombinieren
function p.linkAndShortdesc(frame)
  local args = getArgs(frame)
  local entityId = detectEntityId(args)
  if not entityId then
    return ''
  end

  local mode = args.mode or args.typ or args.type
  local label = args.label or args.text

  local short = buildShortdescText(entityId, mode)
  local link  = buildEntityLink(entityId, label)

  local out = {}
  if short and short ~= '' then
    short = trim(short):gsub('\n', ' ')
    table.insert(out, string.format('{{SHORTDESC:%s}}', short))
  end
  if link and link ~= '' then
    table.insert(out, link)
  end

  return table.concat(out, '\n')
end

return p