Zum Inhalt springen

Modul:P703

aus Wikipedia, der freien Enzyklopädie

Beschreibung

[Quelltext bearbeiten]

Dieses Modul zeigt Organismen aus der Wikidata-Eigenschaft P703 („gefunden in Taxon“) mit Inline-Zitaten an, die direkt aus Wikidata-Referenzen extrahiert wurden. Es ist vollständig eigenständig‚ und hat keine externen Modulabhängigkeiten, sodass es leicht auf alle Wikimedia-Projekte übertragen werden kann.

Hauptmerkmale

[Quelltext bearbeiten]
  • Keine Abhängigkeiten: Keine Abhängigkeit von sprachspezifischen Zitier- oder Wikidata-Modulen
  • Inline-Zitate: Extrahiert und formatiert automatisch bibliografische Daten aus Wikidata
  • Intelligente Interwiki-Verlinkung: Verlinkt zu lokalen Artikeln, Fallback zu anderen Sprachen oder Wikidata
  • Hochgradig konfigurierbar: Anpassbare Anzeigeanzahl und Zitierverhalten
  • Internationalisierungsfähig: Einfach zu übersetzen über i18n-Tabelle

Grundlegende Syntax

[Quelltext bearbeiten]
{{#invoke:P703|main}}

Mit benutzerdefinierten Parametern

[Quelltext bearbeiten]
{{#invoke:P703|main|qid=Q3613679|numval=10|sources=true}}

In Infoboxen

[Quelltext bearbeiten]
|organisms={{#if: {{#property:P703}} | {{#invoke:P703|main}} | }}
Parameter Beschreibung Standardwert Gültige Werte
qid Wikidata-Entitäts-ID für die Abfrage QID der aktuellen Seite Jeder gültige Q-Identifikator (z. B. Q3613679)
numval Maximale Anzahl der anzuzeigenden Organismen 5 Jede positive ganze Zahl
sources Inline-Zitate anzeigen true true, false, yes, no

Das Modul passt seine Ausgabe an die Anzahl der gefundenen Organismen an:

Szenario Ausgabeformat Beispiel
Keine Organismen Gibt die lokalisierte Meldung „kein bekannter Organismus” zurück kein bekannter Organismus
1–n Organismen Zeigt die Anzahl und die vollständige Liste an 3 Organismen: Mensch, Maus, Ratte
Mehr als n Organismen Zeigt die Anzahl mit dem Präfix „darunter” an 15 Organismen, darunter: Mensch, Maus, Ratte, Hund, Katze

Beispiel 1: Standardverwendung (aktuelle Seite)

[Quelltext bearbeiten]
{{#invoke:P703|main}}

Ausgabe: 2 Organismen: Mensch, Maus

Beispiel 2: Spezifische Entität

[Quelltext bearbeiten]
{{#invoke:P703|main|qid=Q3613679}}

Ausgabe: Zeigt Organismen für Wikidata-Element Q3613679 an.

Beispiel 3: 20 Organismen anzeigen

[Quelltext bearbeiten]
{{#invoke:P703|main|numval=20}}

Ausgabe: 25 Organismen, darunter: [die ersten 20 Organismen]

Beispiel 4: Ohne Quellenangaben

[Quelltext bearbeiten]
{{#invoke:P703|main|sources=false}}

Ausgabe: 5 Organismen: Mensch, Maus, Ratte, Hund, Katze (keine Referenz-Tags)

Beispiel 5: Alle Parameter kombinieren

[Quelltext bearbeiten]
{{#invoke:P703|main|qid=Q2079986|numval=3|sources=true}}

Ausgabe: 10 Organismen, darunter: Organismus₁[1], Organismus₂[2], Organismus₃[3]

Zitierformat

[Quelltext bearbeiten]

Wenn sources=true (Standard), extrahiert und formatiert das Modul automatisch bibliografische Daten aus Wikidata-Referenzen:

Unterstützte Felder:

  • Autoren (bis zu 3, dann „et al.“)
  • Artikeltitel (mit optionaler URL)
  • Name der Zeitschrift (kursiv)
  • Band (fett) und Ausgabenummer
  • Seitenzahlen
  • Erscheinungsjahr
  • DOI- und PMID-Kennungen

Beispiel für eine Zitierung:

Smith J, Jones A, Williams B et al. „Protein Expression in Model Organisms”. 
Nature Genetics 45 (3): S. 123–130. (2023). doi:10.1038/ng.3456. pmid:12345678.

Logik der Interwiki-Verlinkung

[Quelltext bearbeiten]

Das Modul wählt für jeden Organismus intelligent den besten Link aus:

  1. Lokaler Wiki-Artikel vorhanden → [[Lokaler Artikel|Bezeichnung]]
  2. Artikel existiert in einem anderen Wiki → Bezeichnung (lang)
  3. Kein Artikel gefunden → Bezeichnung (d)

Dadurch wird sichergestellt, dass Benutzer immer auf Informationen über den Organismus zugreifen können, auch wenn kein lokaler Artikel vorhanden ist.

Internationalisierung

[Quelltext bearbeiten]

Um dieses Modul für andere Sprachen anzupassen, bearbeiten Sie die Tabelle i18n im Code:

local i18n = {
    no_organism = „aucun organisme connu“,     -- Französisches Beispiel
    including = „dont“,
    wd_label = „d“,
    separator = „, “,
    organism = „organisme“,
    organisms = „organismes“
}

Technische Details

[Quelltext bearbeiten]

Leistungsoptimierungen

[Quelltext bearbeiten]
  • Entity Caching: Verhindert redundante API-Aufrufe für referenzierte Quellen
  • Lazy Evaluation: Ruft Daten nur bei Bedarf ab
  • Effiziente Anspruchsverarbeitung: Stoppt bei numval-Limit

Keine Abhängigkeiten

[Quelltext bearbeiten]

Im Gegensatz zu den meisten Modulen ist P703 vollständig eigenständig:

  • Kein Module:LanguageSpecificModule
  • Nur direkte Verwendung der Wikibase-API

Dadurch ist es:

  • Einfach auf jedem Wikimedia-Projekt einzusetzen
  • Ohne externe Modul-Updates wartbar
  • Konsistent über verschiedene Sprach-Wikis hinweg

Fehlerbehandlung

[Quelltext bearbeiten]
Szenario Modulantwort
Keine QID angegeben Verwendet das Wikidata-Element der aktuellen Seite.
Ungültige QID Gibt „kein bekannter Organismus” zurück.
Keine P703-Behauptungen Gibt „kein bekannter Organismus” zurück.
Fehlende Referenzdaten Lässt die Zitierung elegant weg
Fehlerhafte Zitierdaten Enthält nur verfügbare Felder

Dieses Modul wird unter CC0 (Public Domain) veröffentlicht. Es kann ohne Quellenangabe in jedem Wikimedia-Projekt angepasst, übersetzt und eingesetzt werden.


  1. ↑ ...
  2. ↑ ...
  3. ↑ ...
--[[
╔════════════════════════════════════════════════════════════════════════════╗
║ Module:P703 - Organism Display with Inline Citations                       ║
║                                                                            ║
║ Author: AdrianoRutz                                                        ║
║ License: CC0 / Public Domain                                               ║
║                                                                            ║
║ Description:                                                               ║
║   Displays organisms (P703 "found in taxon") with formatted citations      ║
║   extracted directly from Wikidata references. Zero external dependencies. ║
║                                                                            ║
║ Usage:                                                                     ║
║   {{#invoke:P703|main|qid=Q2079986|numval=5|sources=true}}                 ║
║                                                                            ║
║ Parameters:                                                                ║
║   - qid: Wikidata entity ID (defaults to current page)                     ║
║   - numval: Maximum organisms to display (default: 5)                      ║
║   - sources: Show inline citations (default: true)                         ║
╚════════════════════════════════════════════════════════════════════════════╝
--]]
local p = {}

--[[────────────────────────────────────────────────────────────────────────────
  SECTION 1: CONFIGURATION & INTERNATIONALIZATION
────────────────────────────────────────────────────────────────────────────]]
-- Localization strings - edit these for language-specific deployments
local i18n = {
    no_organism = "kein Organismus bekannt",
    including = "darunter",
    wd_label = "d", -- Label for Wikidata link
    separator = ", ", -- List separator
    organism = "Organismus", -- Singular form
    organisms = "Organismen" -- Plural form
}

-- Entity cache prevents redundant API calls for the same Wikidata item
local entityCache = {}

--[[────────────────────────────────────────────────────────────────────────────
  SECTION 2: CITATION ENGINE
  
  Extracts and formats bibliographic data from Wikidata references.
  Supports: authors, title, journal, volume, issue, pages, DOI, PMID, dates
────────────────────────────────────────────────────────────────────────────]]
--- Safely extracts a property value from a Wikidata entity
-- @param entity table The Wikidata entity object
-- @param prop string The property ID (e.g., "P1476")
-- @return string|nil The property value or nil if not found
local function getPropertyValue(entity, prop)
    local claims = entity.claims and entity.claims[prop]
    if not claims or not claims[1].mainsnak.datavalue then
        return nil
    end

    local datavalue = claims[1].mainsnak.datavalue.value

    -- Handle different datavalue types
    if type(datavalue) == "table" then
        return datavalue.text or datavalue.id or datavalue.time
    end

    return datavalue
end

--- Extracts and formats author list from Wikidata
-- @param entity table The source entity containing author claims
-- @param maxAuthors number Maximum authors to list before "et al."
-- @return string|nil Formatted author string or nil
local function getAuthors(entity, maxAuthors)
    maxAuthors = maxAuthors or 3

    local authorClaims = entity.claims and (entity.claims.P50 or entity.claims.P2093)
    if not authorClaims then
        return nil
    end

    local authors = {}
    for i, snak in ipairs(authorClaims) do
        if i > maxAuthors then
            table.insert(authors, "et al.")
            break
        end

        if snak.mainsnak.datavalue then
            local authorValue = snak.mainsnak.datavalue.value
            local authorId = (type(authorValue) == "table") and authorValue.id or authorValue
            table.insert(authors, mw.wikibase.getLabel(authorId) or authorId)
        end
    end

    return #authors > 0 and table.concat(authors, ", ") or nil
end

--- Generates formatted citation from Wikidata reference
-- @param frame table MediaWiki frame object (for extensionTag)
-- @param claim table The Wikidata claim containing references
-- @return string Formatted MediaWiki reference(s) or empty string
local function getCleanRef(frame, claim)
    if not claim.references then
        return ""
    end

    local refs = {}

    for _, ref in ipairs(claim.references) do
        local cite = {}
        local sourceQid = nil

        -- Extract source (P248 = "stated in")
        if ref.snaks and ref.snaks.P248 then
            sourceQid = ref.snaks.P248[1].datavalue.value.id
        end

        if sourceQid then
            -- Use cached entity if available to reduce API calls
            local srcEntity = entityCache[sourceQid] or mw.wikibase.getEntity(sourceQid)

            if srcEntity then
                entityCache[sourceQid] = srcEntity

                -- Extract bibliographic metadata
                cite.title = getPropertyValue(srcEntity, "P1476") or mw.wikibase.getLabel(sourceQid)
                cite.journal = mw.wikibase.getLabel(getPropertyValue(srcEntity, "P1433"))
                cite.vol = getPropertyValue(srcEntity, "P478")
                cite.issue = getPropertyValue(srcEntity, "P433")
                cite.pages = getPropertyValue(srcEntity, "P304")
                cite.doi = getPropertyValue(srcEntity, "P356")
                cite.pmid = getPropertyValue(srcEntity, "P698")
                cite.authors = getAuthors(srcEntity, 3)

                -- Extract publication year from date
                local rawDate = getPropertyValue(srcEntity, "P577")
                if type(rawDate) == "string" then
                    cite.date = rawDate:match("+?(%d%d%d%d)")
                end
            end
        elseif ref.snaks and ref.snaks.P854 then
            -- Fallback to URL reference (P854 = "reference URL")
            cite.url = ref.snaks.P854[1].datavalue.value
        end

        -- Assemble citation in bibliographic format
        local parts = {}

        -- Authors
        if cite.authors and cite.authors ~= "" then
            table.insert(parts, cite.authors .. ".")
        end

        -- Title (with optional URL)
        if cite.title then
            local titleStr = cite.url and ("[" .. cite.url .. ' "' .. cite.title .. '"]') or ('"' .. cite.title .. '"')
            table.insert(parts, titleStr .. ".")
        elseif cite.url then
            table.insert(parts, "[" .. cite.url .. " Wikidata Source].")
        end

        -- Journal information
        if cite.journal then
            local journalStr = "''" .. cite.journal .. "''"

            if cite.vol then
                journalStr = journalStr .. " '''" .. cite.vol .. "'''"
            end
            if cite.issue then
                journalStr = journalStr .. " (" .. cite.issue .. ")"
            end
            if cite.pages then
                journalStr = journalStr .. ": pp. " .. cite.pages
            end

            table.insert(parts, journalStr .. ".")
        end

        -- Publication date
        if cite.date then
            table.insert(parts, "(" .. cite.date .. ").")
        end

        -- Identifiers
        if cite.doi then
            table.insert(parts, "[[doi:" .. cite.doi .. "|doi:" .. cite.doi .. "]].")
        end
        if cite.pmid then
            table.insert(parts, "[[pmid:" .. cite.pmid .. "|pmid:" .. cite.pmid .. "]].")
        end

        -- Create MediaWiki reference tag
        if #parts > 0 then
           table.insert(refs, frame:extensionTag("ref", table.concat(parts, " ")))
        end
    end
    
    -- Using a span with vertical-align: super ensures it matches the ref marker height exactly
    return table.concat(refs, '<span style="vertical-align: 0.9em; font-size: 0.7em;">,</span>')
end

--[[────────────────────────────────────────────────────────────────────────────
  SECTION 3: DYNAMIC INTERWIKI LINKING
  
  Creates smart links that:
  1. Link to local wiki article if it exists
  2. Link to another language wiki with lang code if no local article
  3. Link to Wikidata as fallback
────────────────────────────────────────────────────────────────────────────]]
--- Generates optimal interwiki link for a Wikidata item
-- @param itemId string The Wikidata Q-identifier
-- @return string Formatted wikilink with fallback to interwiki or Wikidata
local function getDynamicLink(itemId)
    local label = mw.wikibase.getLabel(itemId) or itemId
    local entity = mw.wikibase.getEntity(itemId)
    local sitelinks = (entity and entity.sitelinks) or {}

    -- Priority 1: Local wiki article
    local currentWiki = mw.language.getContentLanguage():getCode() .. "wiki"
    if sitelinks[currentWiki] then
        return "[[" .. sitelinks[currentWiki].title .. "|" .. label .. "]]"
    end

    -- Priority 2: First available interwiki link (excluding Wikidata/Commons)
    for wiki, data in pairs(sitelinks) do
        if wiki:match("wiki$") and wiki ~= "wikidatawiki" and wiki ~= "commonswiki" then
            local langCode = wiki:gsub("wiki$", ""):gsub("_", "-")
            return label .. " <small>([[:" .. langCode .. ":" .. data.title .. "|" .. langCode .. "]])</small>"
        end
    end

    -- Priority 3: Wikidata fallback
    return label .. " <small>([[:d:" .. itemId .. "|" .. i18n.wd_label .. "]])</small>"
end

--[[────────────────────────────────────────────────────────────────────────────
  SECTION 4: MAIN ENTRY POINT
────────────────────────────────────────────────────────────────────────────]]
--- Main function to display organism list with citations
-- @param frame table MediaWiki frame object containing arguments
-- @return string Formatted organism list with references
function p.main(frame)
    -- Handle both direct invoke and template parameter passing
    local args = frame.args
    if not args.qid or args.qid == "" then
        args = frame:getParent().args
    end

    -- Extract parameters with defaults
    local qid = (args.qid and args.qid ~= "") and args.qid or mw.wikibase.getEntityIdForCurrentPage()
    local numval = tonumber(args.numval) or 5
    local showSources = (args.sources ~= "false" and args.sources ~= "no")

    -- Validate entity and P703 claims exist
    local entity = mw.wikibase.getEntity(qid)
    if not entity or not entity.claims or not entity.claims.P703 then
        return i18n.no_organism
    end

    -- Process claims
    local claims = entity.claims.P703
    local count = #claims
    local results = {}

    for i = 1, math.min(count, numval) do
        local claim = claims[i]
        if claim.mainsnak and claim.mainsnak.datavalue then
            local id = claim.mainsnak.datavalue.value.id
            local link = getDynamicLink(id)
            local ref = showSources and getCleanRef(frame, claim) or ""
            table.insert(results, link .. ref)
        end
    end

    -- Format output with proper pluralization
    local lang = mw.getContentLanguage()
    local label = lang:plural(count, i18n.organism, i18n.organisms)
    local listStr = table.concat(results, i18n.separator)

    if count > numval then
        return count .. " " .. label .. ", " .. i18n.including .. ": " .. listStr
    else
        return count .. " " .. label .. ": " .. listStr
    end
end

--[[────────────────────────────────────────────────────────────────────────────
  SECTION 5: METATABLE FOR DIRECT INVOCATION
  
  Allows calling the module as {{#invoke:P703|...}} or simply {{P703|...}}
────────────────────────────────────────────────────────────────────────────]]
setmetatable(
    p,
    {
        __call = function(t, frame)
            return p.main(frame)
        end
    }
)

return p