Zum Inhalt springen

Gespräch:Wikibase Einrichtung nach Einstallung

aus AufEinWort, der freien Forschung

Über diese Seite Gespräch

wir haben nun offenbar Wikibase mit Repo und Client
ChatGPT Sophos GPT-5
25. November 2025 n. Chr. erst.  
11:19 Uhr Ausgabe 02
Ausgabe 02
unüberarbeitet ungeprüft

Hallo Sophos,

wir haben nun offenbar Wikibase mit Repo und Client und mit WikibaseLexemen auf eigenem MediaWiki mit Semantic MediaWiki lauffägig, also ohne erkennbare technische Fehler und Mängel "am Start".

Einige Q's, P's und L's habe ich zum est angelegt und nun geht es darm daß ich kennenlerne, wie ich die Daten der Q's, P's und L's, also die Datem der Items, Properties und Lexeme in meinem MediaWiki in Wikiseiten verwenden und darstellen kann.

Gebe mir dazu einen groben Überblick und jeweils ein kleines Beispiel, sodaß ich dessen Funktionsumfang und Funktionsweise erkennen kann.

ChatGPT:

(25. Nov. 2025, 11:19)

Hallo Nikolaos! Kurzer, strukturierter Überblick, wie du Q-, P- und L-Daten in normalen Wikiseiten nutzt – jeweils mit Mini-Beispiel zum direkten Ausprobieren.

1) Schnell & simpel: Parserfunktionen des Clients

Voraussetzung: Wikibase Client ist aktiv und Datentransklusion ist erlaubt. Dann kannst du Werte direkt in Wikitext holen.

Beispiele

  • Wert einer Property vom „Standard-Item“ der Seite (über Sitelink verknüpft):
    {{#property:P569}}
    
  • Wert einer Property von einem expliziten Item:
    {{#property:P569|from=Q42}}
    


Das from=Q… ist offiziell dokumentiert; für einfache Fälle reicht #property. Für komplexere Darstellungen ist Lua gedacht. mediawiki.org+1

Hinweis: #statements (Mehrfachwerte) existiert im Client; Syntax/Formatierung unterscheiden sich je nach Version. Für präzise Kontrolle empfehle ich Lua (Abschnitt 2). mediawiki.org

2) Flexibel & mächtig: Lua (Scribunto) mit mw.wikibase

Voraussetzungen:

  • allowDataTransclusion im Client.
  • Für Zugriff per ID von beliebigen Seiten zusätzlich „arbitrary access“ aktivieren (allowArbitraryDataAccess). Die Doku weist darauf hin, dass getEntity('Q…') sonst gesperrt ist. mediawiki.org+1

2a. Label/Beschreibung/Sitelink eines Items

-- In einem Modul:
local p = {}
function p.label(frame)
  local id = frame.args.id -- z.B. Q42
  return mw.wikibase.getLabel(id) or ''
end
return p

Aufruf in Wikitext:

{{#invoke:WB|label|id=Q42}}

Alternativen: getLabelByLang(id,'de'), getDescription(id), getSitelink('Q42'). doc.wikimedia.org 2b. Statements (inkl. Formatierung des Datentyps)

-- Modul:WB
local p = {}
function p.claim(frame)
  local id = frame.args.id      -- z.B. Q42
  local prop = frame.args.p     -- z.B. P569
  local st = mw.wikibase.getBestStatements(id, prop)
  if not st or #st == 0 then return '' end
  -- formatiert Datentyp korrekt (Zeit, Item-Link, Zahl, URL, …)
  return mw.wikibase.formatValue(st[1].mainsnak)
end
return p

Wikitext:

Geboren: {{#invoke:WB|claim|id=Q42|p=P569}}

getBestStatements liefert „preferred“ sonst „normal“, nie „deprecated“; formatValue rendert typbewusst. doc.wikimedia.org

Performance-Hinweis (Fakt): Viele getEntity-Aufrufe gelten als „expensive“; nach ~14 anderen Entitäten muss erneut geladen werden. Für Infoboxen also gezielt bündeln. doc.wikimedia.org

3) Lexeme (L-, Form-, Sense-Daten) via Lua

Voraussetzung zusätzlich: $wgLexemeEnableDataTransclusion = true. Dann stellt WikibaseLexeme eine eigene Lua-API bereit.

Beispiele

  • Lemma holen (in „de“):
    local l = mw.wikibase.getEntity('L1')
    local lemma, lang = l:getLemma('de')
    return lemma or ''
    
  • Alle Formen mit ihren Repräsentationen ausgeben:
    local l = mw.wikibase.getEntity('L1')
    local out = {}
    for _, form in ipairs(l:getForms()) do
      local rep, rlang = form:getRepresentation('de')
      if rep then table.insert(out, rep) end
    end
    return table.concat(out, ', ')
    
  • Gloss(en) einer Sense:
    local s = mw.wikibase.getEntity('L1-S1')
    local gloss = s:getGloss('de')  -- returns text, 'de'
    return gloss or ''
    

Die genannten Methoden (getLemma, getForms, getSenses, form:getRepresentation, sense:getGloss, …) sind offiziell dokumentiert. doc.wikimedia.org

4) Brücke zu Semantic MediaWiki (Werte persistieren und abfragbar machen)

Ziel: Daten aus Wikibase ziehen und als SMW-Property setzen, damit du mit #ask/#show arbeiten kannst.

Minimal-Pattern

-- Modul:WB
local p = {}
function p.claim(frame)
  local st = mw.wikibase.getBestStatements(frame.args.id, frame.args.p)
  if not st or #st==0 then return '' end
  return mw.wikibase.formatValue(st[1].mainsnak)
end
return p

Wikitext auf einer Seite:

{{#set:hat Geburtsdatum={{#invoke:WB|claim|id=Q42|p=P569}}}}

Jetzt ist hat Geburtsdatum in SMW gespeichert und per #ask abfragbar. (Details zu #set siehe SMW-Doku.) semantic-mediawiki.org

Praxis-Hinweis: SMW speichert den ausgegebenen Text. Für maschinenfreundliche Werte (z. B. ISO-Datum, Q-IDs) ggf. zusätzlich eine „Rohwert“-Variante zurückgeben und getrennt in SMW ablegen (z. B. hat Geburtsdatum (ISO)).

5) Konfiguration – einmal prüfen

  • Client-Datentransklusion (allowDataTransclusion) → nötig für Parserfunktionen/Lua-Zugriff. mediawiki.org
  • Arbitrary access (allowArbitraryDataAccess) → nötig, wenn du in beliebigen Seiten per ID auf Entitäten zugreifst. doc.wikimedia.org
  • Lexeme-Transklusion ($wgLexemeEnableDataTransclusion) → nötig für L/Form/Sense-Lua. doc.wikimedia.org

6) Mini-Kochbuch (direkt nutzbar)

  • Item-Label (de):
    {{#invoke:WB|label|id=Q64}}
    
  • Item-URL:
    return mw.wikibase.getEntityUrl('Q64')
    

doc.wikimedia.org

  • Item-Property „instance of“ (P31) als Link:
    local st = mw.wikibase.getBestStatements('Q64','P31')
    return (#st>0) and mw.wikibase.formatValue(st[1].mainsnak) or ''
    

doc.wikimedia.org

  • Lexeme-Lemma (de):
    local lemma = mw.wikibase.getEntity('L99'):getLemma('de')
    

doc.wikimedia.org

Wenn du willst, setze ich dir als Nächstes ein kleines, versionsneutrales Modul Modul:WB

mit 3–4 sauberen Funktionen (Label, 1-Wert-Statement, Mehrfach-Statement-Liste, Lexeme-Snippet) plus eine Vorlage für die SMW-Brücke auf. Sag mir nur kurz, welche P-IDs du in deinen ersten Infoboxen brauchst.

Du:

In Local Settings ist folgendes bereits gesetzt:

$wgallowArbitraryDataAccess = true; $wgLexemeEnableDataTransclusion = true;

Wie prüfe ich ob ich die Voraussetzungen für Datentransklusion erfülle?

ch habe in eine Wikiseite "{{#property:P9}}" ohne jegliche erkennbare Auswirkung eingefügt. Welchen Effekt müßte dies haben?

ChatGPT:

Kurzfassung vorweg:

  • {{#property:P9}} zeigt nur dann etwas an, wenn die aktuelle Wikiseite per Sitelink mit einem Item verknüpft ist und dieses Item eine Aussage mit P9 hat.
  • Ohne Sitelink musst du from=Q… angeben: {{#property:P9|from=Q123}}.

1) Konfiguration richtig setzen (prüfen)

Bitte vergewissere dich, dass die Client-Settings exakt so in der LocalSettings.php stehen (Groß/Kleinschreibung und Array-Schlüssel sind wichtig):

// Wikibase Client: Datentransklusion
$wgWBClientSettings['allowDataTransclusion'] = true;

// Optional (für Zugriffe per ID von beliebigen Seiten):
$wgWBClientSettings['allowArbitraryDataAccess'] = true;

// Lexeme-Transklusion (für L/Form/Sense via Lua)
$wgLexemeEnableDataTransclusion = true;

Hinweis: Ein Eintrag wie $wgallowArbitraryDataAccess = true; (ohne WBClientSettings) hat keine Wirkung.

Schnellcheck: Auf Special:Version müssen „Wikibase Repository“ und „Wikibase Client“ gelistet sein.

2) Minimal-Tests (sofort ausführbar)

Test A – Parserfunktion funktioniert & Arbitrary Access aktiv

Setze das auf eine beliebige Wikiseite (die nicht verlinkt sein muss):

{{#property:P31|from=Q1}}

Erwartung: Eine Ausgabe (z. B. ein Link/Label).

Wenn leer: Entweder allowDataTransclusion/allowArbitraryDataAccess nicht aktiv, oder Q1/P31 existiert in deiner Datenbasis nicht.

  1. Lege ein Item z. B. Q100 an und gib ihm eine Aussage P9 = Beispielwert.
  2. Verknüpfe dein Seiten-Titel via Sitelink mit Q100.
  3. Auf die verknüpfte Seite schreibe:
    {{#property:P9}}
    

Erwartung: Beispielwert erscheint.

Wenn leer: Entweder kein Sitelink zur Seite, P9 am Item fehlt, oder P9 ist ein anderer Datentyp ohne sichtbare Darstellung.

Praxis: Für schnelle Prüfungen ist Special:ExpandTemplates hilfreich. Dort denselben Wikitext testen und die direkte Expansion anschauen.

3) Typische Ursachen für „keine Ausgabe“

  1. Kein Sitelink der Seite auf ein Item → {{#property:P9}} bleibt leer. Lösung: Sitelink anlegen oder from=Q… verwenden.
  2. Property/Statement fehlt: P9 existiert nicht, oder das Item hat kein P9. Lösung: P9 anlegen und auf dem Item befüllen.
  3. Config nicht wirksam: allowDataTransclusion/allowArbitraryDataAccess nicht (korrekt) gesetzt. Lösung: s. Abschnitt 1, Cache leeren (?action=purge), ggf. PHP/OPcache/Webserver neu laden.
  4. Caching: Nach Änderungen an Items/Statements die Zielseite purgen (?action=purge) oder einmal neu speichern.

4) Erwartetes Verhalten (Beispiele)

  • String / External-ID / Zahl {{#property:P9|from=Q123}} → gibt den Zeichenstring/ID/Wert aus (z. B. Beispiel-123).
  • wikibase-item (z. B. P31 „ist ein(e)“)
    {{#property:P31|from=Q42}}
    
    → gibt das Label des Ziel-Items (mit Link) aus, z. B. Mensch.
  • Zeit/Datum
    {{#property:P569|from=Q42}}
    
    → formatiertes Datum (z. B. 11. März 1952), abhängig von deinen Locale-Einstellungen.

Für präzisere Kontrolle (Mehrfachwerte, Formatierung, Rohwerte) ist Lua (mw.wikibase) robuster. Aber für „schnell mal anzeigen“ reicht #property.

5) Wenn du sofort weiterkommen willst

Sag mir eine konkrete Q-ID und Property-ID aus deinem Bestand (z. B. Q123 mit P9), dann prüfe ich dir die passenden Einzeiler:

  • Parserfunktion: {{#property:P9|from=Q123}}
  • Lua-Variante inkl. Rohwert (z. B. ISO-Datum) + optionaler SMW-Setzung (#set) für spätere #ask-Abfragen.

Du:

Danke für die ersten groben Erklärungen. Ich habe LocalSettings.php entsprechend "

1) Konfiguration richtig setzen (prüfen)" berichtigt – danke.

Zum Test der Funktion habe ich {{#property:P9|from=Q6}} in eine Wikiseite eingefügt. Dabei ist P9 "hat Wort" und Q6 "Dingwort" und als Antwort erhalte ich "L2" in der Wikiseite, was wiederum L2 "Dingwort" ist.

Diese haben noch keinen Sinn, da nur zum Test angelegt. So erkenne ich nun das Muster: Die Eingaben und Abfrageergebnisse beschränken sich auf ID's und ID-Kombinationen – richtig?

ChatGPT:

Kurz: Nein — die Ausgabe ist nicht auf reine IDs beschränkt.

Was du siehst („L2“) liegt am Datentyp deiner Property.

  • Bei String/URL/Zahl/Zeit gibt {{#property:…}} formatierten Text/Link/Zahl/Datum aus.
  • Bei wikibase-item zeigt #property in der Regel das Label (mit Link) des Ziel-Items.
  • Bei wikibase-lexeme (so wirkt dein P9 = „hat Wort“) gibt die Standardformatierung meist die Lexeme-ID (z. B. „L2“) aus – nicht das Lemma. Dafür brauchst du Lua.

Warum bei dir „L2“: P9 verweist auf ein Lexem → Standardformat zeigt die Seitenkennung des Lexems. Inhaltlich „Dingwort“ (Lemma) bekommst du über Lua.

Zwei schnelle Wege zur „sprechenden“ Ausgabe

A) Item-Labels (ohne Lua)

Wenn eine Property auf Item zeigt:

{{#property:P31|from=Q6}}

→ ergibt das Label des Ziel-Items (z. B. „Substantiv“), sofern vorhanden.

B) Lexem-Lemma (mit Lua)

Lege ein kleines Modul an, z. B. Modul:WB:

Aufruf auf deiner Seite (für dein Beispiel):

local p = {}

-- 1) Allgemein: bestes Statement hübsch formatiert (Items, Zeiten, Zahlen, …)
function p.claim(frame)
  local id = frame.args.id
  local prop = frame.args.p
  if not id or not prop then return '' end
  local st = mw.wikibase.getBestStatements(id, prop)
  if not st or #st == 0 then return '' end
  return mw.wikibase.formatValue(st[1].mainsnak) or ''
end

-- 2) Speziell: Property -> Lexem-ID holen und Lemma in gewünschter Sprache ausgeben
function p.claimLexemeLemma(frame)
  local id   = frame.args.id
  local prop = frame.args.p
  local lang = frame.args.lang or 'de'
  if not id or not prop then return '' end

  local st = mw.wikibase.getBestStatements(id, prop)
  if not st or #st == 0 then return '' end
  local snak = st[1].mainsnak
  if not (snak and snak.datavalue and snak.datavalue.value and snak.datavalue.value.id) then
    return ''
  end

  local lexId = snak.datavalue.value.id -- z. B. "L2"
  local e = mw.wikibase.getEntity(lexId)
  if not e then return lexId end  -- Fallback: ID zeigen
  local lemma = nil
  -- getLemma gibt (text, lang) zurück:
  local text, _ = e:getLemma(lang)
  lemma = text or nil
  return lemma or lexId
end

return p

→ Erwartung: „Dingwort“.

(Falls das Lexem noch kein deutsches Lemma hat, kommt Fallback „L2“.)

Bonus: gleich für SMW speichern

Wenn du die Werte später per #ask abfragen willst, schreibe zusätzlich auf die Seite:

{{#set:
 hat Wort (Lemma)={{#invoke:WB|claimLexemeLemma|id=Q6|p=P9|lang=de}}
}}

Für Sortierung/Filterung kann es sinnvoll sein, Lemma (lesbar) und Roh-ID (z. B. „L2“) getrennt in zwei SMW-Properties zu speichern.

Checkliste, wenn nichts kommt

  1. Seite purgen (?action=purge) oder einmal neu speichern.
  2. Stimmt der Datentyp der Property (Item vs. Lexem)?
  3. Hat das Ziel-Lexem ein Lemma in lang=de?
  4. Deine Client-Settings:
    • $wgWBClientSettings['allowDataTransclusion'] = true;
    • $wgWBClientSettings['allowArbitraryDataAccess'] = true; (für from=Q…)
    • $wgLexemeEnableDataTransclusion = true;

Wenn du willst, erweitere ich das Modul noch um:

  • label(id) (Item-Label robust),
  • claimsList(id, p) (alle Werte, komma-getrennt),
  • lexemeForms(id, lang) (Form-Liste).

Sag mir kurz, welche P-IDs/Fälle du als Nächstes brauchst.

Du:

Das sind hilfreiche Informationen.

WIr haben bereits zum Test Modul:WikibaseLink entworfen. Derzeit zeigt mir vergleichsweise {{WikibaseLink|L=L2}} nur die dann verlinkten ID's an, wobei ich L2 manuell angeben muß, während Lua mir aus dem Seitennamen den Link zum entsprechenden Item generiert.

Ich habe festgestellt, daß ich nur Q-Seiten mittels WikibaseSiteLink mit Wikiseiten verknüpfen kann, Lexeme bleiben außen vor.

Mir erscheint Lexeme als ein spätes Anhängsel und daß sich bei Wikibase an sich alles um Q's und P's dreht.

Ich habe also Q6 "Dingwort" über WikibaseSiteLink mit der Wikiseite "Dingwort" verknüpft.

Ich habe in die Wikiseite "Dingwort" nun {{#property:P9}} eingefügt und erhalte ohne "from=…" nun L2 und verstehe, wenn ich anstelle von L2 den Begriff oder Begriff und ID angezeigt bekommen will, daß mittels #invoke oder Vorlage tun muß. Was kann ich nun damit Weiteres auf der Wikiseite "Dingwort" mittels Wikibase tun?

ChatGPT:

Klar – gute Beobachtungen (Lexeme haben keine Sitelinks; #property nutzt bei verlinkten Seiten das zugehörige Q-Item). Auf „Dingwort“ (Q6) kannst du jetzt mehrere sinnvolle Dinge direkt aus Wikibase ziehen und anzeigen. Hier ist eine kleine „Werkzeugkiste“ mit sofort nutzbaren Snippets.

1) Basis: Item-Metadaten anzeigen (Label, Beschreibung, Aliasse)

Lua-Modul (Modul:WB) – Minimalfunktionen

local p = {}

-- Q-ID der aktuellen Seite (per Sitelink)
function p.currentId()
  return mw.wikibase.getEntityIdForCurrentPage() or ''
end

-- Label / Beschreibung / Aliasse eines Items
function p.label(frame)
  local id = frame.args.id or p.currentId()
  return (id ~= '' and (mw.wikibase.getLabel(id) or '')) or ''
end
function p.desc(frame)
  local id = frame.args.id or p.currentId()
  return (id ~= '' and (mw.wikibase.getDescription(id) or '')) or ''
end
function p.aliases(frame)
  local id = frame.args.id or p.currentId()
  if id == '' then return '' end
  local e = mw.wikibase.getEntity(id); if not e or not e:getAliases() then return '' end
  local a = e:getAliases('de') or {}
  local out = {}
  for _, v in ipairs(a) do table.insert(out, v.value) end
  return table.concat(out, ', ')
end

return p

Aufruf auf „Dingwort“:

2) Statements eines Items (ein Wert, mehrere Werte, formatiert)

Lua – generisch für beliebige Properties

-- in Modul:WB ergänzen
local function best(id, p) return mw.wikibase.getBestStatements(id, p) or {} end

function p.claim(frame)
  local id = frame.args.id or mw.wikibase.getEntityIdForCurrentPage()
  local prop = frame.args.p
  if not id or not prop then return '' end
  local st = best(id, prop); if #st == 0 then return '' end
  return mw.wikibase.formatValue(st[1].mainsnak) or ''
end

function p.claims(frame)  -- alle Werte, komma-getrennt
  local id = frame.args.id or mw.wikibase.getEntityIdForCurrentPage()
  local prop = frame.args.p; local sep = frame.args.sep or ', '
  if not id or not prop then return '' end
  local st = best(id, prop); if #st == 0 then return '' end
  local out = {}
  for _, s in ipairs(st) do table.insert(out, mw.wikibase.formatValue(s.mainsnak) or '') end
  return table.concat(out, sep)
end

function p.claimWithQuals(frame) -- erster Wert + Qualifikatoren
  local id = frame.args.id or mw.wikibase.getEntityIdForCurrentPage()
  local prop = frame.args.p
  if not id or not prop then return '' end
  local st = best(id, prop); if #st == 0 then return '' end
  local s = st[1]; local text = mw.wikibase.formatValue(s.mainsnak) or ''
  if s.qualifiers then
    local parts = {}
    for qprop, qs in pairs(s.qualifiers) do
      local qvals = {}
      for _, q in ipairs(qs) do table.insert(qvals, mw.wikibase.formatValue(q)) end
      table.insert(parts, qprop .. ': ' .. table.concat(qvals, ', '))
    end
    if #parts > 0 then text = text .. ' (' .. table.concat(parts, ' | ') .. ')' end
  end
  return text
end

Aufrufbeispiele auf „Dingwort“ (Q6):

;hat Wort (P9), „bester“ Wert: {{#invoke:WB|claim|p=P9}}
;hat Wort (alle Werte): {{#invoke:WB|claims|p=P9}}
;hat Wort (mit Qualifikatoren): {{#invoke:WB|claimWithQuals|p=P9}}

Bei dir ist P9 vom Typ Lexeme – die Standardformatierung gibt die ID (L2) zurück. „Sprechend“ werden Lexeme über die Lexeme-API (nächster Abschnitt).

3) Lexeme anzeigen: Lemma, Formen, Senses (über P→L)

Lua – Lemma & Formen aus einem Property, das auf ein Lexem zeigt (z. B. P9)

-- in Modul:WB ergänzen
local function firstLexemeId(id, prop)
  local st = mw.wikibase.getBestStatements(id, prop) or {}
  if #st == 0 then return nil end
  local sn = st[1].mainsnak
  if sn and sn.datavalue and sn.datavalue.value and sn.datavalue.value.id then
    return sn.datavalue.value.id -- z. B. "L2"
  end
end

function p.lexemeLemmaFrom(frame)
  local id = frame.args.id or mw.wikibase.getEntityIdForCurrentPage()
  local prop = frame.args.p; local lang = frame.args.lang or 'de'
  if not id or not prop then return '' end
  local L = firstLexemeId(id, prop); if not L then return '' end
  local e = mw.wikibase.getEntity(L); if not e then return L end
  local text = (e.getLemma and e:getLemma(lang)) or nil
  if type(text) == 'table' then text = text[1] end  -- falls API zwei Werte liefert
  return text or L
end

function p.lexemeFormsFrom(frame)
  local id = frame.args.id or mw.wikibase.getEntityIdForCurrentPage()
  local prop = frame.args.p; local lang = frame.args.lang or 'de'
  if not id or not prop then return '' end
  local L = firstLexemeId(id, prop); if not L then return '' end
  local e = mw.wikibase.getEntity(L); if not e or not e.getForms then return '' end
  local out = {}
  for _, form in ipairs(e:getForms()) do
    local repr = form.getRepresentation and form:getRepresentation(lang)
    local txt = (type(repr) == 'table') and repr[1] or repr
    if txt then table.insert(out, txt) end
  end
  return table.concat(out, ', ')
end

Aufruf auf „Dingwort“:

;Lemma (de) aus P9→L: {{#invoke:WB|lexemeLemmaFrom|p=P9|lang=de}}
;Formen (de) aus P9→L: {{#invoke:WB|lexemeFormsFrom|p=P9|lang=de}}

Erweiterbar: Senses (Gloss), grammatische Merkmale der Formen (form:getGrammaticalFeatures() → Q-IDs → getLabel).

4) „Rückwärtslisten“ (wer zeigt auf Q6?) – zwei Wege

A) Ohne Query-Service – über SMW-Brücke

Wenn du auf den Seiten (oder Item-Darstellungen) beim Speichern SMW-Properties setzt, kannst du auf „Dingwort“ Rückwärtsabfragen machen:

{{#set:ist AufEinWort (Q-ID)=Q6}}

Dann z. B.:

== Verwendet in ==
{{#ask:
 [[ist AufEinWort (Q-ID)\:\:Q6]]
 | ?Seitenname
 | format=ul
}}

Muster: Du spiegelst ausgewählte Wikibase-Aussagen als SMW-Fakten; damit sind #ask-Listen trivial.

B) Mit lokalem Query-Service (SPARQL)

Falls du einen WDQS/Fuseki angebunden hast, kannst du auf „Dingwort“ SPARQL-Resultate einbinden (z. B. „alle Items mit P31 = Q6“). Das ist abhängig von deiner Einbindung; wenn gewünscht, liefere ich dir eine konkrete SPARQL-Vorlage.

5) Nützliche Links/Debug

Auf „Dingwort“ einblenden:

* [[Special:EntityPage/{{#invoke:WB|currentId}}|Item-Seite]]
* [{{#invoke:WB|entityUrl}} JSON]

Lua-Helfer:

function p.entityUrl(frame)
  local id = frame.args.id or mw.wikibase.getEntityIdForCurrentPage()
  return id and mw.wikibase.getEntityUrl(id) or ''
end

function p.dump(frame) -- JSON-Dump (nur für Testzwecke)
  local id = frame.args.id or mw.wikibase.getEntityIdForCurrentPage()
  local e = id and mw.wikibase.getEntity(id) or nil
  return e and mw.text.jsonEncode(e, { indent = 2 }) or ''
end

6) Saubere Präsentation (Infobox-Pattern)

Lege eine kleine Vorlage an (z. B. Vorlage:WB-Datenblatt) und nutze nur #invoke-Zeilen darin. Auf „Dingwort“ bindest du nur {{WB-Datenblatt}} ein. Vorteil: zentral wartbar, klarer Trenner zwischen Anzeige und Datenzugriff.


7) Praxis-Hinweise

  • Purge nach Datenänderungen (?action=purge) oder die Seite einmal neu speichern.
  • Ranks: getBestStatements nimmt „preferred“ vor „normal“; „deprecated“ wird ignoriert.
  • Leere Werte bewusst leer lassen (kein „n/a“), damit SMW/Abfragen sauber unterscheiden können.
  1. automatisch die Q-ID der aktuellen Seite nutzt,
  2. bei Lexeme-Properties das Lemma statt der L-ID zeigt (mit Fallback),
  3. optional gleich SMW-Properties setzt (Lemma + Roh-ID), damit du auf „Dingwort“ sofort Rückwärtslisten via #ask bekommst.

Du:

Soweit so gut. Wenn ich in einer Wikiseite zu einer Person mit WikibaseSiteLink innerhalb eines Fließtext dessen Geburtsdatum anzeigen lassen will – wie mache ich das?

ChatGPT:

Kurz & direkt:

Inline im Fließtext – drei praxistaugliche Varianten

1) Einfach (auf der verlinkten Personenseite)

Wenn die Wikiseite per WikibaseSiteLink mit dem Personen-Item verknüpft ist:

Er wurde am {{#property:P569}} geboren.
  • P569 = Geburtsdatum.
  • Ausgabe ist lokalisiert (z. B. „11. März 1952“).
  • Fehlt die Aussage, bleibt es leer → besser Variante 2 nutzen.
2) Mit Fallback (nur anzeigen, wenn vorhanden)
{{#if:{{#property:P569}}|Er wurde am {{#property:P569}} geboren.|Geburtsdatum unbekannt}}
3) Von einer anderen Seite aus (ohne Sitelink)

Du erwähnst eine Person in einem anderen Artikel:

… (geboren am {{#property:P569|from=Q42}}) …

(Q42 durch die Q-ID der Person ersetzen.)

Mehr Kontrolle (Lua), z. B. nur Jahr / Monat+Jahr

Lege ein kleines Modul an, z. B. Modul:WBDatum:

local p = {}

local function bestStatement(id, prop)
  local st = mw.wikibase.getBestStatements(id, prop)
  return (st and st[1]) or nil
end

-- formatiert Datum abhängig von Präzision:
-- day -> "j. F Y", month -> "F Y", year -> "Y"
function p.geburtsdatum(frame)
  local id  = frame.args.id  or mw.wikibase.getEntityIdForCurrentPage()
  local fmt = frame.args.fmt -- optional: "auto" (Voreinstellung), "day", "month", "year", "iso"
  if not id then return '' end
  local s = bestStatement(id, 'P569'); if not s then return '' end
  local sn = s.mainsnak
  local v  = sn and sn.datavalue and sn.datavalue.value
  if not v or not v.time then return '' end

  local time = v.time                -- z. B. "+1952-03-11T00:00:00Z"
  local prec = v.precision or 11     -- 11=Tag, 10=Monat, 9=Jahr
  local y,m,d = time:match("^%+?(%-?%d+)%-(%d%d)%-(%d%d)")

  -- ISO sofort zurückgeben
  if fmt == 'iso' then
    return string.format("%s-%s-%s", y, m, d)
  end

  -- MW-Timestamp bauen (YYYYMMDDhhmmss)
  local function ts(yy, mm, dd)
    return string.format("%s%s%s000000", yy, mm, dd)
  end
  local lang = mw.language.getContentLanguage()

  if fmt == 'day' or (fmt == nil and prec >= 11) then
    return lang:formatDate('j. F Y', ts(y, m, d))
  elseif fmt == 'month' or (fmt == nil and prec == 10) then
    return lang:formatDate('F Y', ts(y, m, '01'))
  elseif fmt == 'year' or (fmt == nil and prec == 9) then
    return y
  else
    -- Fallback: Wikibase-Standardformatierung (z. B. bei ungewöhnlichen Fällen)
    return mw.wikibase.formatValue(sn) or ''
  end
end

return p

Aufrufe im Fließtext:

Er wurde am {{#invoke:WBDatum|geburtsdatum}} geboren.

(auf der Personen-Seite mit Sitelink)

… (geb. {{#invoke:WBDatum|geburtsdatum|id=Q42|fmt=year}}) …

(nur das Jahr, z. B. „1800“)

… (geboren {{#invoke:WBDatum|geburtsdatum|id=Q42|fmt=month}}) …

(z. B. „März 1800“)

… ({{#invoke:WBDatum|geburtsdatum|id=Q42|fmt=iso}}) …

(ISO „YYYY-MM-DD“, nützlich für SMW)

Optional: gleich für SMW speichern

Wenn du das Datum für Abfragen brauchst:

{{#set:
 hat Geburtsdatum={{#invoke:WBDatum|geburtsdatum}} |
 hat Geburtsdatum (ISO)={{#invoke:WBDatum|geburtsdatum|fmt=iso}}
}}

Typische Stolperstellen

  • Kein Sitelink → {{#property:P569}} liefert nichts (Variante mit from=Q… oder Lua+id= nutzen).
  • Präzision: Wikibase speichert Jahres-/Monats-/Tagesgenauigkeit; die Lua-Variante berücksichtigt das automatisch.
  • Caching: Nach Datenänderungen Seite purgen (?action=purge) oder kurz neu speichern.

Wenn du mir eine konkrete Q-ID nennst, prüfe ich dir die Ausgabeform (Tag/Monat/Jahr) direkt am Beispiel und passe die Formatierung an deinen Stil an („geboren am … in …“ zusammen mit P19).

Du:

Wenn ich dies nutze, dann wird jede Wikiseite einer PÜerson auch sein entsprechendes Q und SitLink haben.

Ich würde sozusagen die Wikibase-Q's als die Metadaten der jeweilgen Seite verwenden, jedoch würde ich mit eine inline-Vorlage erstellen wie {{Geburtstag|fmt=Jahr}} erstellen und alles Weitere Lua und der Vorlage erledigen lassen.

Unmittelbar mit Wikibase in Wikiseiten zu arbeiten ist aufgrund der bedingten Kenntnis der ID's menschlich ungeeignet.

Mir wird erst jetzt bewußt wie nachteilig es ist, daß Wikibase keine Formulare für die Datenerfassung bei der Anlage eines Q's hat.

Laß uns nun erst die sogenannte "Brücke zu Semantic MediaWiki" näher untersuchen. "Extension:Semantic Wikibase" von Semantic MediaWiki für Wikibase ist sozusagen tot, mangels Gelder und Programmierer langfristig "auf Eis gelegt".

Wikibase ist für machinelles Lesen für eine KI entworfen, nicht für den Mensch. Semantic Wikibase wäre also die Lösung Wikibase für Menschen nutzbar zu machen – oder?

ChatGPT:

Dein Ansatz ist stimmig: Q-Items als „Metadaten-Master“ der Personen-Seiten, und in den Fließtext nur kleine, sprechende Vorlagen wie {{Geburtstag|fmt=Jahr}}. Für Mensch-Lesbarkeit + Abfragen brauchen wir die WB→SMW-Brücke. Hier ist ein praxistaugliches, schlankes Muster (ohne zusätzliche Extensions), das zuverlässig funktioniert.

Zielbild (einseitige Brücke)

  • Quelle: Wikibase (Q/P/L) – maschinenlesbar, „Single Source of Truth“.
  • Spiegel: SMW-Properties auf der Personen-Wikiseite – menschen-/abfragefreundlich.
  • Mechanik: Lua liest aus WB → Template setzt SMW-Werte via #set → du nutzt #ask/Infobox/Fließtext.

Änderungen in Items triggern über den Client die Neuberechnung der Seiten, die das Item verwenden. Dadurch werden auch SMW-Werte aktualisiert (bei nächster Re-Parse/Purge). Ein manueller „Write-Back“ nach Wikibase ist nicht Teil dieser Brücke (einseitig WB→SMW).

Schritt 1 – SMW-Properties anlegen (minimaler Kern)

Lege (als Beispiel) folgende Property-Seiten an:

  • Property:hat Q-ID → Type: Text (oder String)
  • Property:hat Geburtsdatum → Type: Date
  • Property:hat Geburtsdatum (ISO) → Type: Text (optional; nur wenn du ISO separat willst)
  • Property:hat Geburtsort (Q-ID) → Type: Text
  • Property:hat Geburtsort (Label) → Type: Text (entspr. für Tod: hat Sterbedatum, hat Sterbeort (Q-ID), … (Label))

Hinweis: Für Item-Bezüge speichere Q-ID (stabil, abfragbar) und Label (lesbar) getrennt. Labels können sprach- und zeitabhängig sein.

Schritt 2 – Lua-Modul Modul:WB2SMW

Ein kleines, robustes Modul, das Roh- und Anzeige-Werte liefert:

local p = {}

local function currentId()
  return mw.wikibase.getEntityIdForCurrentPage()
end

local function best(id, prop)
  local st = mw.wikibase.getBestStatements(id, prop)
  if st and st[1] then return st[1] end
end

-- Zeit: ISO + lokalisierte Ausgabe (Präzision beachtet)
local function parseTimeSnak(snak)
  local v = snak and snak.datavalue and snak.datavalue.value
  if not v or not v.time then return nil end
  local time = v.time                 -- "+1952-03-11T00:00:00Z"
  local prec = v.precision or 11      -- 11=Tag,10=Monat,9=Jahr
  local y,m,d = time:match("^%+?(-?%d+)%-(%d%d)%-(%d%d)")
  if not y then return nil end
  local iso = string.format("%s-%s-%s", y, m, d)
  local lang = mw.language.getContentLanguage()
  local function ts(yy, mm, dd) return string.format("%s%s%s000000", yy, mm, dd) end
  local display
  if prec >= 11 then
    display = lang:formatDate('j. F Y', ts(y, m, d))
  elseif prec == 10 then
    display = lang:formatDate('F Y', ts(y, m, '01'))
  else
    display = y
  end
  return { iso = iso, display = display }
end

-- wikibase-item: Q-ID + Label
local function itemVal(snak)
  local v = snak and snak.datavalue and snak.datavalue.value
  if not v or not v['entity-type'] or not v['id'] then return nil end
  local qid = v.id
  local label = mw.wikibase.getLabel(qid) or qid
  return { id = qid, label = label }
end

-- öffentlich nutzbare Helfer:

function p.birthDate(frame) -- P569
  local id = frame.args.id or currentId()
  if not id then return '' end
  local s = best(id, 'P569'); if not s then return '' end
  local t = parseTimeSnak(s.mainsnak); if not t then return '' end
  local fmt = frame.args.fmt
  if fmt == 'iso' then return t.iso end
  if fmt == 'year' then return (t.iso:sub(1,4)) end
  return t.display
end

function p.place(frame) -- generisch für Orte: P19 (Geburt), P20 (Tod) etc.
  local id = frame.args.id or currentId()
  local prop = frame.args.p
  if not id or not prop then return '' end
  local s = best(id, prop); if not s then return '' end
  local it = itemVal(s.mainsnak); if not it then return '' end
  local mode = frame.args.mode or 'label'
  if mode == 'id' then return it.id end
  return it.label
end

-- Lexeme: z. B. Name als Lemma (falls du so modellierst)
function p.lexemeLemma(frame) -- erwartet Property, die auf L zeigt
  local id = frame.args.id or currentId()
  local prop = frame.args.p; local lang = frame.args.lang or 'de'
  if not id or not prop then return '' end
  local s = best(id, prop); if not s then return '' end
  local v = s.mainsnak and s.mainsnak.datavalue and s.mainsnak.datavalue.value
  local lid = v and v.id
  if not lid then return '' end
  local e = mw.wikibase.getEntity(lid); if not e or not e.getLemma then return lid end
  local text = e:getLemma(lang)
  if type(text) == 'table' then text = text[1] end -- API-Variation
  return text or lid
end

return p

Schritt 3 – Template Vorlage:WB-Bruecke-Person

Dieses Template zeigt nichts an, setzt aber beim Speichern die SMW-Werte:

<!-- Geburtsdatum -->
{{#set:hat Geburtsdatum={{#invoke:WB2SMW|birthDate}} }}
{{#set:hat Geburtsdatum (ISO)={{#invoke:WB2SMW|birthDate|fmt=iso}} }}

<!-- Geburtsort -->
{{#set:hat Geburtsort (Q-ID)={{#invoke:WB2SMW|place|p=P19|mode=id}} }}
{{#set:hat Geburtsort (Label)={{#invoke:WB2SMW|place|p=P19|mode=label}} }}

<!-- Optional: Q-ID der Seite selbst (für Querverweise/Join) -->
{{#set:hat Q-ID={{#invoke:WB|currentId}} }}

Erweitere nach Bedarf (Sterbedatum P570 / Sterbeort P20, Staatsbürgerschaft P27, Beruf P106 …). Für jede P-ID: (Q-ID)+ (Label) getrennt speichern.

Wichtig: Binde das Template einmal weit oben ein (z. B. in deiner Personen-Infobox oder einem unsichtbaren Metadaten-Block). Beim nächsten Speichern/Neu-Parse landen die Werte in SMW.

Schritt 4 – Fließtext-Vorlagen (menschlich nutzbar)

Jetzt kannst du für den Fließtext schlanke Vorlagen anbieten:

  • Vorlage:Geburtstag:
    {{#switch: {{{fmt|voll}}}
     | iso = {{#invoke:WB2SMW|birthDate|fmt=iso}}
     | Jahr = {{#invoke:WB2SMW|birthDate|fmt=year}}
     | #default = {{#invoke:WB2SMW|birthDate}}
    }}
    

Nutzung:

Er wurde am {{Geburtstag}} in {{#invoke:WB2SMW|place|p=P19}} geboren.

oder nur das Jahr: geb. {{Geburtstag|fmt=Jahr}}.

So vermeidest du überall IDs; Menschen sehen nur fertigen Text.

Schritt 5 – Abfragen (Beispiel)

Auf einer Liste/Chronikseite:

== Geboren im März 1800 ==
{{#ask:
 [[hat Geburtsdatum\:\:>=1800-03-01]]
 [[hat Geburtsdatum\:\:<=1800-03-31]]
 | ?hat Geburtsort (Label)=Geburtsort
 | ?hat Q-ID
 | format=table
 | limit=200
}}

Hinweise, Grenzen, Feinschliff

  • Nachladen/Änderungen: Wenn du Daten im Item änderst, sorgt der Client für Re-Render der nutzenden Seite; SMW-Werte werden beim nächsten Parse aktualisiert. Bei Bedarf ?action=purge.
  • Dubletten vermeiden: Schreibe nur Werte, die du für #ask/Navigation brauchst (Q-ID, ISO-Datum, Label). Lange Texte/Listen nicht blind spiegeln.
  • Performanz: Lieber ein zentrales Template mit einigen wenigen #invoke-Aufrufen als viele verstreute. Lua-Funktionen bündeln.
  • Lexeme: L-IDs nie direkt im Fließtext anzeigen; immer Lemma/Forms über Lua holen. Für SMW maximal Lemma + L-ID speichern, wenn du darauf abfragen willst.
  • Editier-UX: Für menschliche Erfassung eignen sich SMW-/PageForms-Formulare hervorragend; Master bleibt aber WB. (Wer schreibt, ist eine bewusste Prozessfrage: Willst du Eingaben primär in WB erfassen, oder in SMW und später nach WB migrieren? Die hier gezeigte Brücke ist bewusst „WB→SMW“.)

Sofort anwendbares Minimal-Set

  1. Lege die Properties an (oben).
  2. Kopiere Modul:WB2SMW.
  3. Lege Vorlage:WB-Bruecke-Person an (oben).
  4. Binde die Vorlage auf einer Personen-Seite mit Sitelink ein.
  5. Nutze {{Geburtstag|fmt=Jahr}} im Fließtext.

Wenn du magst, setze ich dir das konkret für deine P-IDs um (z. B. P569/P19/P570/P20 + dein P9→Lexem-Lemma) und erweitere das Modul um eine kleine Mapping-Tabelle (P→SMW-Propertyname + Zieltyp).

ChatGPT kann Fehler machen. Überprüfe wicht