Zeile 12: |
Zeile 12: |
| ["property-not-found"] = "Eigenschaft nicht gefunden.", | | ["property-not-found"] = "Eigenschaft nicht gefunden.", |
| ["entity-not-found"] = "Wikidata-Eintrag nicht gefunden.", | | ["entity-not-found"] = "Wikidata-Eintrag nicht gefunden.", |
| + | ["entity-not-valid"] = "Die an die Wikidata-Schnittstelle übergebene Item-ID ist nicht gültig.", |
| ["unknown-claim-type"] = "Unbekannter Aussagentyp.", | | ["unknown-claim-type"] = "Unbekannter Aussagentyp.", |
| ["unknown-entity-type"] = "Unbekannter Entity-Typ.", | | ["unknown-entity-type"] = "Unbekannter Entity-Typ.", |
Zeile 62: |
Zeile 63: |
| [14] = {"s","U"} --precision: second | | [14] = {"s","U"} --precision: second |
| } | | } |
− |
| |
− | local p = {}
| |
| | | |
| local function printError(code) | | local function printError(code) |
Zeile 138: |
Zeile 137: |
| end | | end |
| do return false end | | do return false end |
− | end
| |
− |
| |
− | function p.isSubclass(frame)
| |
− | if not frame.args["parent"] then return false end
| |
− |
| |
− | local maxDepth
| |
− | maxDepth = frame.args["maxDepth"] or 5
| |
− | if not type(maxDepth) == "number" then maxDepth = 5 end
| |
− |
| |
− | local result
| |
− | result = isParent(frame.args["id"], frame.args["parent"], frame.args["exitItem"], maxDepth)
| |
− | if frame.args["returnInt"] then
| |
− | if result == true then return 1 else return 0 end
| |
− | else
| |
− | return result
| |
− | end
| |
− | end
| |
− |
| |
− | function p.descriptionIn(frame)
| |
− | local langcode = frame.args[1]
| |
− | local id = frame.args[2]
| |
− | -- return description of a Wikidata entity in the given language or the default language of this Wikipedia site
| |
− | local entity = mw.wikibase.getEntity(id)
| |
− | if entity and entity.descriptions then
| |
− | local desc = entity.descriptions[langcode or wiki.langcode]
| |
− | if desc then return desc.value end
| |
− | end
| |
− | end
| |
− |
| |
− | function p.labelIn(frame)
| |
− | local langcode = frame.args[1]
| |
− | local id = frame.args[2]
| |
− | -- return label of a Wikidata entity in the given language or the default language of this Wikipedia site
| |
− | local entity = mw.wikibase.getEntity(id)
| |
− | if entity and entity.labels then
| |
− | local label = entity.labels[langcode or wiki.langcode]
| |
− | if label then return label.value end
| |
− | end
| |
| end | | end |
| | | |
Zeile 353: |
Zeile 314: |
| if qualifierId then | | if qualifierId then |
| -- search the attribute snak with the given qualifier as key | | -- search the attribute snak with the given qualifier as key |
− | if claim.qualifiers then | + | if claim and claim.qualifiers then |
| local qualifier = claim.qualifiers[qualifierId] | | local qualifier = claim.qualifiers[qualifierId] |
| if qualifier then return qualifier[1] end | | if qualifier then return qualifier[1] end |
Zeile 429: |
Zeile 390: |
| function formatReference(ref) | | function formatReference(ref) |
| -- "imported from"-references are useless, skip them: | | -- "imported from"-references are useless, skip them: |
− | if ref["P143"] then return nil end | + | if ref["P143"] or ref["P4656"] then return nil end |
| | | |
| -- load [[Modul:Zitation]] | | -- load [[Modul:Zitation]] |
Zeile 435: |
Zeile 396: |
| if type(r) == "table" then | | if type(r) == "table" then |
| Zitation = r.Zitation() | | Zitation = r.Zitation() |
| + | -- clear Zitation state from previous invocations |
| + | Zitation.o = nil |
| end | | end |
| -- assert (ZitationSuccess, i18n["errors"]["module-not-loaded"]) | | -- assert (ZitationSuccess, i18n["errors"]["module-not-loaded"]) |
Zeile 481: |
Zeile 444: |
| local URLutil = Zitation.fetch("URLutil") | | local URLutil = Zitation.fetch("URLutil") |
| Zitation.fill("bas", "Titel", URLutil.getHost(ref["P854"])) | | Zitation.fill("bas", "Titel", URLutil.getHost(ref["P854"])) |
− | elseif not (ref["P1476"]) then
| |
− | Zitation.fill("bas", "Titel", ref["P854"])
| |
| end | | end |
| refFormatted, f = Zitation.format() | | refFormatted, f = Zitation.format() |
− | return refFormatted | + | return refFormatted, f |
| end | | end |
| | | |
Zeile 505: |
Zeile 466: |
| end | | end |
| end | | end |
− | local formattedRef = formatReference(refTable) | + | local formattedRef, f = formatReference(refTable) |
− | if formattedRef then result = result .. frame:extensionTag("ref", formattedRef) end | + | -- log errors that occur during formatting |
| + | if f then |
| + | mw.log(f) |
| + | end |
| + | if formattedRef and formattedRef ~= "" then |
| + | local hash = mw.hash.hashValue('fnv164', formattedRef) |
| + | result = result .. frame:extensionTag("ref", formattedRef, { name = '_' .. hash }) |
| + | end |
| end | | end |
| return result | | return result |
Zeile 520: |
Zeile 488: |
| if invert and claim.qualifiers[string.sub(qualifierproperty, 2)] then return false end | | if invert and claim.qualifiers[string.sub(qualifierproperty, 2)] then return false end |
| return true | | return true |
| + | end |
| + | |
| + | local function qualifierhasvalue(claim, property, value) |
| + | -- TODO: not yet documented! |
| + | if not claim.qualifiers then return false end |
| + | if not claim.qualifiers[property] then return false end |
| + | for key, snak in pairs(claim.qualifiers[property]) do |
| + | if snak.snaktype == "value" then |
| + | if snak.datavalue.type == "wikibase-entityid" then |
| + | if snak.datavalue.value.id == value then |
| + | return true |
| + | end |
| + | --TODO: elseif other types |
| + | end |
| + | end |
| + | end |
| + | return false |
| end | | end |
| | | |
Zeile 560: |
Zeile 545: |
| | | |
| return true | | return true |
| + | end |
| + | |
| + | local function notdeprecated(claim, sourceproperty) |
| + | return not (claim.rank == "deprecated") |
| end | | end |
| | | |
Zeile 580: |
Zeile 569: |
| filter('hassource', hassource) | | filter('hassource', hassource) |
| filter('atdate', atdate) | | filter('atdate', atdate) |
| + | if not frame.args.includedeprecated then |
| + | frame.args.notdeprecated = true |
| + | filter('notdeprecated', notdeprecated) |
| + | end |
| + | |
| + | -- use additional unnamed parameters as qualifier conditions (in pairs) |
| + | -- not yet documented! |
| + | -- TODO: not sure if this is good approach. Maybe use named parameter that has pairs split by semicolon |
| + | for key, val in pairs(frame.args) do |
| + | if type(key) == "number" and key > 2 and key % 2 == 1 then |
| + | -- key = 3, 5, 7 and so on |
| + | local newclaims = {} |
| + | for i, claim in pairs(claims) do |
| + | if qualifierhasvalue(claim, frame.args[key - 1], frame.args[key]) then |
| + | table.insert(newclaims, claim) |
| + | end |
| + | end |
| + | claims = newclaims |
| + | end |
| + | end |
| + | |
| + | return claims |
| + | end |
| + | |
| + | local p = {} |
| + | |
| + | function p.isSubclass(frame) |
| + | if not frame.args["parent"] then return "" end |
| + | |
| + | local maxDepth |
| + | maxDepth = frame.args["maxDepth"] or 5 |
| + | if not type(maxDepth) == "number" then maxDepth = 5 end |
| | | |
− | return claims | + | local result |
| + | result = isParent(frame.args["id"], frame.args["parent"], frame.args["exitItem"], maxDepth) |
| + | |
| + | if frame.args["returnInt"] then |
| + | if result == true then return 1 else return "" end |
| + | else |
| + | if result then return result else return false end |
| + | end |
| + | |
| + | end |
| + | |
| + | function p.descriptionIn(frame) |
| + | local langcode = frame.args[1] |
| + | local id = frame.args[2] |
| + | -- return description of a Wikidata entity in the given language or the default language of this Wikipedia site |
| + | local entity = mw.wikibase.getEntity(id) |
| + | if entity and entity.descriptions then |
| + | local desc = entity.descriptions[langcode or wiki.langcode] |
| + | if desc then return desc.value end |
| + | else |
| + | return ""; |
| + | end |
| + | end |
| + | |
| + | function p.labelIn(frame) |
| + | local langcode = frame.args[1] |
| + | local id = frame.args[2] |
| + | -- return label of a Wikidata entity in the given language or the default language of this Wikipedia site |
| + | if mw.wikibase then |
| + | local entity = mw.wikibase.getEntity(id) |
| + | end |
| + | if entity and entity.labels then |
| + | local label = entity.labels[langcode or wiki.langcode] |
| + | if label then return label.value end |
| + | else |
| + | return ""; |
| + | end |
| end | | end |
| | | |
Zeile 602: |
Zeile 659: |
| | | |
| -- get wikidata entity | | -- get wikidata entity |
− | local entity = mw.wikibase.getEntity(id) | + | if id then |
| + | if not mw.wikibase.isValidEntityId(id) then |
| + | if showerrors then return printError("entity-not-valid") else return default end |
| + | elseif not mw.wikibase.entityExists(id) then |
| + | if showerrors then return printError("entity-not-found") else return default end |
| + | end |
| + | end |
| + | |
| + | if mw.wikibase then |
| + | local entity = mw.wikibase.getEntity(id) |
| + | end |
| if not entity then | | if not entity then |
| if showerrors then return printError("entity-not-found") else return default end | | if showerrors then return printError("entity-not-found") else return default end |
Zeile 625: |
Zeile 692: |
| local comparator | | local comparator |
| if sort then | | if sort then |
− | -- sort by time qualifier
| + | comparator = function(a, b) --comparator function for sorting statements based on qualifier value |
− | comparator = function(a, b) | + | -- load qualifier values |
− | local timea = getQualifierSortValue(claims[a], sort) or '' | + | local QualifierSortValueA = getQualifierSortValue(claims[a], sort) |
− | local timeb = getQualifierSortValue(claims[b], sort) or '' | + | local QualifierSortValueB = getQualifierSortValue(claims[b], sort) |
− | if type(timea) ~= type(timeb) and not (tonumber(timea) and tonumber(timeb)) then | + | |
− | if tonumber(timea) then return true | + | -- if either of the two statements does not have this qualifer, always sort it to the end. If neither of the two statements has this qualifier, statement A is ordered first |
− | elseif tonumber(timeb) then return false | + | if not QualifierSortValueB then return true end |
− | elseif tostring(timea) and tostring(timeb) then | + | if not QualifierSortValueA then return false end |
− | if inverse then return tostring(timea) > tostring(timeb) else return tostring(timea) < tostring(timeb) end | + | |
| + | if type(QualifierSortValueA) ~= type(QualifierSortValueB) and not (tonumber(QualifierSortValueA) and tonumber(QualifierSortValueB)) then |
| + | if tonumber(QualifierSortValueA) then return true |
| + | elseif tonumber(QualifierSortValueB) then return false |
| + | elseif tostring(QualifierSortValueA) and tostring(QualifierSortValueB) then |
| + | if inverse then return tostring(QualifierSortValueA) > tostring(QualifierSortValueB) else return tostring(QualifierSortValueA) < tostring(QualifierSortValueB) end |
| else return false end -- different types, neither numbers nor strings, no chance to compare => random result to avoid script error | | else return false end -- different types, neither numbers nor strings, no chance to compare => random result to avoid script error |
− | elseif tonumber(timea) and tonumber(timeb) then | + | elseif tonumber(QualifierSortValueA) and tonumber(QualifierSortValueB) then |
− | timea = tonumber(timea) | + | QualifierSortValueA = tonumber(QualifierSortValueA) |
− | timeb = tonumber(timeb) | + | QualifierSortValueB = tonumber(QualifierSortValueB) |
| end | | end |
| if inverse then | | if inverse then |
− | return timea > timeb | + | return QualifierSortValueA > QualifierSortValueB |
| else | | else |
− | return timea < timeb | + | return QualifierSortValueA < QualifierSortValueB |
| end | | end |
| end | | end |
Zeile 734: |
Zeile 806: |
| local id = frame.args[1] | | local id = frame.args[1] |
| local entity = mw.wikibase.getEntity(id) | | local entity = mw.wikibase.getEntity(id) |
− | if not entity then return nil else return entity.id end | + | if not entity then return "" else return entity.id end |
| end | | end |
| | | |
Zeile 806: |
Zeile 878: |
| frame.args = newargs | | frame.args = newargs |
| local status, result = pcall(p[func], frame) | | local status, result = pcall(p[func], frame) |
| + | -- if status then return tostring(result) or "" else return '<span class="error">' .. result .. '</span>' end -- revert |
| if status then return result else return '<span class="error">' .. result .. '</span>' end | | if status then return result else return '<span class="error">' .. result .. '</span>' end |
| else | | else |