Module:MathModDBHelperMethods: Difference between revisions
From MaRDI portal
Created page with "-- MediaWiki library for logging and utilities local mw = require('mw') local json = require("mw.text") -- Main table to hold all functions local p = {} -- Function to replace pattern in the comma pattern separated list function p.replace_pattern(frame) local input = frame.args[1] or "" local sep = frame.args[2] or " " -- default to space if no separator given -- Replace comma+pattern (,xxxx) with sep local result = string.gsub(input, ",xxxx%s*", sep..." |
No edit summary |
||
| (62 intermediate revisions by 3 users not shown) | |||
| Line 1: | Line 1: | ||
-- Module for executing SPARQL queries | |||
local sparql = require('SPARQL') | |||
-- Required module containing helper methods | |||
local helper = require('Module:HelperMethods') | |||
-- MediaWiki library for logging and utilities | -- MediaWiki library for logging and utilities | ||
local mw = require('mw') | local mw = require('mw') | ||
| Line 14: | Line 18: | ||
return result | return result | ||
end | end | ||
-- Function to generate a table listing a type of individuals | |||
-- test with =p.getList{args={'Model'}} | |||
function p.getList(frame) | |||
local entityType = frame.args[1] or 'Model' | |||
local height = frame.args[2] or '400px' -- Default height if not specified | |||
local width = frame.args[3] or '800px' -- Default width if not specified | |||
local baseUrl = mw.site.server -- Get the current URL | |||
-- Define mapping of entity types to their corresponding Q IDs and URL prefixes | |||
local entityConfig = { | |||
['Model'] = {qid = 'Q68663', urlPrefix = 'Model:', title = 'mathematical models'}, | |||
['Academic discipline'] = {qid = 'Q60231', urlPrefix = 'Academic_discipline:', title = 'academic disciplines'}, | |||
['Research problem'] = {qid = 'Q6534292', urlPrefix = 'Research_problem:', title = 'research problems'}, | |||
['Task'] = {qid = 'Q6534247', urlPrefix = 'Task:', title = 'computational tasks'}, | |||
['Quantity'] = {qid = 'Q6534237', urlPrefix = 'Quantity:', title = 'quantities'}, | |||
['Quantity kind'] = {qid = 'Q6534245', urlPrefix = 'Quantity:', title = 'quantity kind items'}, | |||
['Formula'] = {qid = 'Q6481152', urlPrefix = 'Formula:', title = 'mathematical expressions'} | |||
} | |||
-- Get configuration for the specified entity type | |||
local config = entityConfig[entityType] | |||
if not config then | |||
return "Invalid entity type. Valid options are: Model, Academic discipline, Research problem, Task, Quantity, Quantity kind, Formula" | |||
end | |||
-- Q6534265 refers to MathModDB community | |||
local sparqlQuery = [[ | |||
SELECT ?itemLabel ?modelURL ?item | |||
WHERE { | |||
?item wdt:P31 wd:]] .. config.qid .. [[; | |||
wdt:P1495 wd:Q6534265 . | |||
?item rdfs:label ?itemLabel . | |||
FILTER(LANG(?itemLabel) = "en") | |||
BIND(REPLACE(STR(?item), "^.*/Q", "]] .. baseUrl .. [[/wiki/]] .. config.urlPrefix .. [[") AS ?modelURL) | |||
} | |||
ORDER BY LCASE(?itemLabel) | |||
]] | |||
local jsonResults = sparql.runQuery(sparqlQuery) | |||
-- Handle error in SPARQL query execution | |||
if jsonResults and jsonResults.error then | |||
mw.log("Error in SPARQL query: " .. tostring(jsonResults.error)) | |||
return nil | |||
end | |||
if not jsonResults then | |||
return "Could not fetch data." | |||
end | |||
if helper.countElementsInBindings(jsonResults.results.bindings) == 0 then | |||
return "No records found." | |||
end | |||
-- Convert the JSON results into a Lua table | |||
local fieldOrder = {"modelURL", "itemLabel", "item"} | |||
local dataTable = helper.convertJsonToTableOrdered(jsonResults, fieldOrder) | |||
-- Create and return HTML table from the data | |||
local headers = {entityType} | |||
local htmlTable = helper.createHtmlTableWithMergedCols(dataTable, headers, {{3}}) | |||
-- Create a parent container for the table | |||
local parentContainer = mw.html.create('div') | |||
:addClass('parent-container') | |||
:css('width', width) | |||
local heading = mw.html.create('h2') | |||
:wikitext('List of ' .. config.title) | |||
-- Add the table and chart to the parent container | |||
parentContainer | |||
:node(heading) | |||
:node(htmlTable) | |||
return tostring(parentContainer) | |||
end | |||
-- Function to get linked items | |||
function p.getLinkedItems(frame) | |||
local entityId = frame.args[1] | |||
-- Validate input parameter | |||
if not entityId or entityId == '' then | |||
return "Error: No entity ID provided" | |||
end | |||
local sparqlQuery = [[ | |||
PREFIX entityId: <https://portal.mardi4nfdi.de/entity/]] .. entityId .. [[> | |||
SELECT DISTINCT ?itemLabel ?item ?propertyLabel ?property | |||
WHERE { | |||
# Replace with your specific entity | |||
?itemInter ?ps entityId: . | |||
# Convert property URL to entity-style URL | |||
BIND( | |||
IRI(REPLACE(STR(?ps), | |||
"^https://portal.mardi4nfdi.de/prop/(direct|qualifier|statement)/", | |||
"https://portal.mardi4nfdi.de/entity/")) | |||
AS ?property | |||
) | |||
# Skip unwanted property | |||
FILTER(?property != <http://schema.org/about>) | |||
# Clean URL: keep only QID, remove /statement/ and trailing UUID | |||
BIND( | |||
IRI( | |||
REPLACE( | |||
STR(?itemInter), | |||
".*/(Q[0-9]+).*", | |||
"https://portal.mardi4nfdi.de/entity/$1" | |||
) | |||
) AS ?item | |||
) | |||
# Get labels | |||
SERVICE wikibase:label { | |||
bd:serviceParam wikibase:language "en". | |||
?item rdfs:label ?itemLabel . | |||
?property rdfs:label ?propertyLabel . | |||
} | |||
} | |||
ORDER BY LCASE(?itemLabel) | |||
]] | |||
-- Executing the SPARQL query and retrieving results in JSON format | |||
local jsonResults = sparql.runQuery(sparqlQuery) | |||
-- Validate results | |||
if not jsonResults or not jsonResults.results or not jsonResults.results.bindings then | |||
return "" | |||
end | |||
local linkedItems = {} | |||
local totalLinkedItems = #jsonResults.results.bindings | |||
if totalLinkedItems >= 0 then | |||
-- Loop through the bindings | |||
for index = 0, totalLinkedItems do | |||
local item = jsonResults.results.bindings[index] | |||
if not item then | |||
return "" | |||
end | |||
if not item.itemLabel or not item.itemLabel.value then | |||
return "" | |||
elseif not item.item or not item.item.value then | |||
return "" | |||
else | |||
local itemLabel = item.itemLabel.value | |||
local itemURL = item.item.value | |||
local propertyLabel = item.propertyLabel and item.propertyLabel.value or "" | |||
local propertyURL = item.property and item.property.value or "" | |||
local itemWithURL = string.format('[%s %s]', tostring(itemURL), tostring(itemLabel)) | |||
local propertyWithURL = string.format('[%s %s]', tostring(propertyURL), tostring(propertyLabel)) | |||
table.insert(linkedItems, '| ' .. itemWithURL .. ' || ' .. propertyWithURL) | |||
end | |||
end | |||
-- if there are linked items | |||
-- Construct the Wikitext table | |||
local wikitextTable = "{| class='wikitable'\n" .. | |||
"! Item\n! Property\n" .. -- header row | |||
"|-\n" .. -- separator before first data row | |||
table.concat(linkedItems, "\n|-\n") .. | |||
"\n|}" | |||
return wikitextTable | |||
else | |||
return "" | |||
end | |||
end | |||
-- Function to get subclass of items | |||
function p.getSubclassOf(frame) | |||
local entityId = frame.args[1] | |||
-- Validate input parameter | |||
if not entityId or entityId == '' then | |||
return "Error: No entity ID provided" | |||
end | |||
-- Constructing the SPARQL query with dynamic entity entityId | |||
-- P36: subclass of property id | |||
local sparqlQuery = [[ | |||
PREFIX entityId: <https://portal.mardi4nfdi.de/entity/]] .. entityId .. [[> | |||
SELECT ?URL ?Label | |||
WHERE { | |||
entityId: wdt:P36 ?URL. | |||
?URL rdfs:label ?Label | |||
FILTER(LANG(?Label) = "en") | |||
} | |||
ORDER BY ?Label | |||
]] | |||
-- Executing the SPARQL query and retrieving results in JSON format | |||
local jsonResults = sparql.runQuery(sparqlQuery) | |||
-- Validate results | |||
if not jsonResults or not jsonResults.results or not jsonResults.results.bindings then | |||
return "No specialized academic discipline found" | |||
end | |||
local subClasses = {} | |||
-- Get the number of specialized academic disciplines | |||
local totalSubClasses = #jsonResults.results.bindings | |||
-- Loop through the bindings | |||
for index = 0, totalSubClasses do | |||
local item = jsonResults.results.bindings[index] | |||
if not item then | |||
return "" | |||
end | |||
if not item.Label.value then | |||
return "" | |||
elseif not item.URL.value then | |||
return "" | |||
else | |||
local label = item.Label.value | |||
local url = item.URL.value | |||
local numericId = url:match("Q(%d+)") | |||
local urlRendered = "https://portal.mardi4nfdi.de/wiki/Academic_discipline:" .. numericId | |||
local labelWithUrl = string.format('[%s %s]', tostring(url), tostring(label)) | |||
table.insert(subClasses, "| " .. labelWithUrl) | |||
end | |||
end | |||
-- Construct the Wikitext table | |||
local wikitextTable = "{| class='wikitable'\n" .. table.concat(subClasses, "\n|-\n") .. "\n|}" | |||
return wikitextTable | |||
end | |||
-- Function to get described by source | |||
function p.getDescribedBySource(frame) | |||
local entityId = frame.args[1] | |||
-- Validate input parameter | |||
if not entityId or entityId == '' then | |||
return "Error: No entity ID provided" | |||
end | |||
-- Constructing the SPARQL query with dynamic entity entityId | |||
-- P286: described by source property id | |||
local sparqlQuery = [[ | |||
PREFIX entityId: <https://portal.mardi4nfdi.de/entity/]] .. entityId .. [[> | |||
SELECT ?URL ?Label | |||
WHERE { | |||
entityId: wdt:P286 ?URL. | |||
?URL rdfs:label ?Label | |||
FILTER(LANG(?Label) = "en") | |||
} | |||
ORDER BY ?Label | |||
]] | |||
-- Executing the SPARQL query and retrieving results in JSON format | |||
local jsonResults = sparql.runQuery(sparqlQuery) | |||
-- Validate results | |||
if not jsonResults or not jsonResults.results or not jsonResults.results.bindings then | |||
return "No specialized academic discipline found" | |||
end | |||
local describedBySources = {} | |||
-- Get the number of specialized academic disciplines | |||
local totalSources = #jsonResults.results.bindings | |||
-- Loop through the bindings | |||
for index = 0, totalSources do | |||
local item = jsonResults.results.bindings[index] | |||
if not item then | |||
return "" | |||
end | |||
if not item.Label.value then | |||
return "" | |||
elseif not item.URL.value then | |||
return "" | |||
else | |||
local label = item.Label.value | |||
local url = item.URL.value | |||
local numericId = url:match("Q(%d+)") | |||
local urlRendered = "https://portal.mardi4nfdi.de/wiki/Academic_discipline:" .. numericId | |||
local labelWithUrl = string.format('[%s %s]', tostring(url), tostring(label)) | |||
table.insert(describedBySources, "| " .. labelWithUrl) | |||
end | |||
end | |||
-- Construct the Wikitext table | |||
local wikitextTable = "{| class='wikitable'\n" .. table.concat(describedBySources, "\n|-\n") .. "\n|}" | |||
return wikitextTable | |||
end | |||
function p.getImageWithLegend(frame) | |||
-- Property ID for the image | |||
local pidImage = "P356" | |||
-- Property ID for the (qualifier) media legend | |||
local pidMediaLegend = "P401" | |||
local defaultLegend = "No legend available." | |||
local entityId = frame.args[1] | |||
-- Validate input parameter | |||
if not entityId or entityId == '' then | |||
return "Error: No entity ID provided" | |||
end | |||
-- Attempt to retrieve entity data | |||
local entity = mw.wikibase.getEntity(entityId) | |||
local imageClaims = entity.claims[pidImage] | |||
local imageStrings = {} | |||
if imageClaims and type(imageClaims) == "table" then | |||
local numClaims = #imageClaims | |||
-- Loop through the image claims | |||
-- for index = 1, numClaims do | |||
local index = 1 | |||
for _, claim in ipairs(imageClaims) do | |||
-- Extract the image filename | |||
-- local imageFilename = imageClaims[index].mainsnak.datavalue.value | |||
local imageFilename = claim.mainsnak.datavalue.value | |||
-- Default legend (empty string) | |||
local imageLegend = "" | |||
-- Check if the media legend qualifier exists | |||
if claim.qualifiers and claim.qualifiers[pidMediaLegend] | |||
and #claim.qualifiers[pidMediaLegend] > 0 | |||
and claim.qualifiers[pidMediaLegend][1].datavalue | |||
and claim.qualifiers[pidMediaLegend][1].datavalue.value | |||
and claim.qualifiers[pidMediaLegend][1].datavalue.value.text then | |||
imageLegend = claim.qualifiers[pidMediaLegend][1].datavalue.value.text | |||
end | |||
-- local imageLegend = imageClaims[index].qualifiers[pidMediaLegend][1].datavalue.value.text | |||
-- Add this image line to the list | |||
-- table.insert(imageStrings, {filename = imageFilename, legend = imageLegend}) | |||
table.insert(imageStrings, string.format("[[File:%s|thumb|380px|%s]]", imageFilename, imageLegend)) | |||
if index < numClaims then | |||
-- spacer column | |||
table.insert(imageStrings, ' ') | |||
end | |||
index = index + 1 | |||
end | |||
-- Combine all image cells into one row of a wikitable | |||
local imageTable = '{| class="wikitable"\n| ' .. table.concat(imageStrings, ' || ') .. '\n|}' | |||
return imageTable .. "\n\n" | |||
else | |||
return "" | |||
end | |||
end | |||
function p.getVideoWithLegend(frame) | |||
-- Property ID for the video | |||
local pidVideo = "P797" | |||
-- Property ID for the (qualifier) media legend | |||
local pidMediaLegend = "P401" | |||
local defaultLegend = "No legend available." | |||
local entityId = frame.args[1] | |||
-- Validate input parameter | |||
if not entityId or entityId == '' then | |||
return "Error: No entity ID provided" | |||
end | |||
-- Attempt to retrieve entity data | |||
local entity = mw.wikibase.getEntity(entityId) | |||
local videoClaims = entity.claims[pidVideo] | |||
local videoStrings = {} | |||
if videoClaims and type(videoClaims) == "table" then | |||
local numClaims = #videoClaims | |||
-- Loop through the image claims | |||
for index = 1, numClaims do | |||
-- Extract the image filename | |||
local videoFilename = videoClaims[index].mainsnak.datavalue.value | |||
local videoLegend = videoClaims[index].qualifiers[pidMediaLegend][1].datavalue.value.text | |||
-- Add this image line to the list | |||
table.insert(videoStrings, string.format("[[File:%s|thumb|340px|%s]]", videoFilename, videoLegend)) | |||
if index < numClaims then | |||
-- spacer column | |||
table.insert(videoStrings, ' ') | |||
end | |||
end | |||
-- Combine all image cells into one row of a wikitable | |||
local videoTable = '{| class="wikitable"\n| ' .. table.concat(videoStrings, ' || ') .. '\n|}' | |||
return videoTable .. "\n\n" | |||
else | |||
return " " | |||
end | |||
end | |||
function p.getLocalImageWithLegend(frame) | |||
-- Property ID for the image | |||
local pidImage = "P1640" | |||
-- Property ID for the (qualifier) media legend | |||
local pidMediaLegend = "P401" | |||
local defaultLegend = "No legend available." | |||
local entityId = frame.args[1] | |||
-- Validate input parameter | |||
if not entityId or entityId == '' then | |||
return "Error: No entity ID provided" | |||
end | |||
-- Attempt to retrieve entity data | |||
local entity = mw.wikibase.getEntity(entityId) | |||
local imageClaims = entity.claims[pidImage] | |||
local imageStrings = {} | |||
if imageClaims and type(imageClaims) == "table" then | |||
local numClaims = #imageClaims | |||
-- Loop through the image claims | |||
for index = 1, numClaims do | |||
-- Extract the image filename | |||
local imageFilename = imageClaims[index].mainsnak.datavalue.value | |||
-- Default legend (empty string) | |||
local imageLegend = "" | |||
-- Check if the media legend qualifier exists | |||
if imageClaims[index].qualifiers and imageClaims[index].qualifiers[pidMediaLegend] | |||
and #imageClaims[index].qualifiers[pidMediaLegend] > 0 | |||
and imageClaims[index].qualifiers[pidMediaLegend][1].datavalue | |||
and imageClaims[index].qualifiers[pidMediaLegend][1].datavalue.value | |||
and imageClaims[index].qualifiers[pidMediaLegend][1].datavalue.value.text then | |||
imageLegend = imageClaims[index].qualifiers[pidMediaLegend][1].datavalue.value.text | |||
end | |||
-- Add this image line to the list | |||
table.insert(imageStrings, string.format("[[File:%s|thumb|380px|%s]]", imageFilename, imageLegend)) | |||
if index < numClaims then | |||
-- spacer column | |||
table.insert(imageStrings, ' ') | |||
end | |||
end | |||
-- Combine all image cells into one row of a wikitable | |||
local imageTable = '{| class="wikitable"\n| ' .. table.concat(imageStrings, ' || ') .. '\n|}' | |||
return imageTable .. "\n\n" | |||
else | |||
return " " | |||
end | |||
end | |||
function p.getLocalVideoWithLegend(frame) | |||
-- Property ID for the video | |||
local pidVideo = "P1675" | |||
-- Property ID for the (qualifier) media legend | |||
local pidMediaLegend = "P401" | |||
local defaultLegend = "No legend available." | |||
local entityId = frame.args[1] | |||
-- Validate input parameter | |||
if not entityId or entityId == '' then | |||
return "Error: No entity ID provided" | |||
end | |||
-- Attempt to retrieve entity data | |||
local entity = mw.wikibase.getEntity(entityId) | |||
local videoClaims = entity.claims[pidVideo] | |||
local videoStrings = {} | |||
if videoClaims and type(videoClaims) == "table" then | |||
local numClaims = #videoClaims | |||
-- Loop through the image claims | |||
for index = 1, numClaims do | |||
-- Extract the image filename | |||
local videoFilename = videoClaims[index].mainsnak.datavalue.value | |||
local videoLegend = videoClaims[index].qualifiers[pidMediaLegend][1].datavalue.value.text | |||
-- Add this image line to the list | |||
table.insert(videoStrings, string.format("[[File:%s|thumb|340px|%s]]", videoFilename, videoLegend)) | |||
if index < numClaims then | |||
-- spacer column | |||
table.insert(videoStrings, ' ') | |||
end | |||
end | |||
-- Combine all image cells into one row of a wikitable | |||
local videoTable = '{| class="wikitable"\n| ' .. table.concat(videoStrings, ' || ') .. '\n|}' | |||
return videoTable .. "\n\n" | |||
else | |||
return " " | |||
end | |||
end | |||
-- Function to get list with qualifier values only | |||
function p.getListWithQualifierValues(frame) | |||
local entityId = frame.args[1] | |||
local propertyId = frame.args[2] | |||
-- Validate input parameter | |||
if not entityId or entityId == '' then | |||
return " " | |||
end | |||
-- Constructing the SPARQL query with dynamic entity entityId | |||
local sparqlQuery = [[ | |||
PREFIX entityId: <https://portal.mardi4nfdi.de/entity/]] .. entityId .. [[> | |||
SELECT ?URL ?Label ?qualPropEntity ?qualPropLabel ?qualValue ?qualValueLabel | |||
WHERE { | |||
entityId: p:]] .. propertyId .. [[ ?statement . | |||
?statement ps:]] .. propertyId .. [[ ?URL . | |||
?URL rdfs:label ?Label | |||
FILTER(LANG(?Label) = "en") | |||
OPTIONAL { | |||
?statement ?qualProp ?qualValue . | |||
FILTER(STRSTARTS(STR(?qualProp), STR(pq:))) # only qualifiers | |||
# Map qualifier property to its property entity | |||
BIND(IRI(REPLACE(STR(?qualProp), "prop/qualifier", "entity")) AS ?qualPropEntity) | |||
OPTIONAL { | |||
?qualPropEntity rdfs:label ?qualPropLabel . | |||
FILTER(LANG(?qualPropLabel) = "en") | |||
} | |||
OPTIONAL { | |||
?qualValue rdfs:label ?qualValueLabel . | |||
FILTER(LANG(?qualValueLabel) = "en") | |||
} | |||
} | |||
} | |||
ORDER BY ?Label | |||
]] | |||
-- Executing the SPARQL query and retrieving results in JSON format | |||
local jsonResults = sparql.runQuery(sparqlQuery) | |||
-- Validate results | |||
if not jsonResults or not jsonResults.results or not jsonResults.results.bindings then | |||
return "No specialized research fields found" | |||
end | |||
local listItems = {} | |||
-- Get the number of specialized research fields | |||
local totallistItems = #jsonResults.results.bindings | |||
-- Loop through the bindings | |||
for index = 0, totallistItems do | |||
local item = jsonResults.results.bindings[index] | |||
if not item.Label.value then | |||
return "Error: Missing item.Label.value" | |||
elseif not item.URL.value then | |||
return "Error: Missing item.URL.value" | |||
else | |||
local label = item.Label.value | |||
local url = item.URL.value | |||
local numericId = url:match("Q(%d+)") | |||
local urlRendered = "https://portal.mardi4nfdi.de/wiki/Model:" .. numericId | |||
local qualValue = item.qualValueLabel or item.qualValue or "" | |||
local labelWithUrl = string.format('[%s %s]', tostring(url), tostring(label)) | |||
if qualValue ~= "" then | |||
local qualValueWithUrl = string.format('[%s %s]', tostring(item.qualValue.value), tostring(item.qualValueLabel.value)) | |||
local row = "| " .. labelWithUrl .. " || (" .. qualValueWithUrl .. ")" | |||
table.insert(listItems, row) | |||
else | |||
table.insert(listItems, "| " .. labelWithUrl) | |||
end | |||
end | |||
end | |||
-- Construct the Wikitext table | |||
local wikitextTable = "{| class='wikitable'\n" .. table.concat(listItems, "\n|-\n") .. "\n|}" | |||
return wikitextTable | |||
end | |||
-- Function to get list with qualifier values and qualifier labels | |||
function p.getListWithQualifierValuesLabels(frame) | |||
local entityId = frame.args[1] | |||
local propertyId = frame.args[2] | |||
-- Validate input parameter | |||
if not entityId or entityId == '' then | |||
return " " | |||
end | |||
-- Constructing the SPARQL query with dynamic entity entityId | |||
local sparqlQuery = [[ | |||
PREFIX entityId: <https://portal.mardi4nfdi.de/entity/]] .. entityId .. [[> | |||
SELECT ?URL ?Label ?qualPropEntity ?qualPropLabel ?qualValue ?qualValueLabel | |||
WHERE { | |||
entityId: p:]] .. propertyId .. [[ ?statement . | |||
?statement ps:]] .. propertyId .. [[ ?URL . | |||
?URL rdfs:label ?Label | |||
FILTER(LANG(?Label) = "en") | |||
OPTIONAL { | |||
?statement ?qualProp ?qualValue . | |||
FILTER(STRSTARTS(STR(?qualProp), STR(pq:))) # only qualifiers | |||
# Map qualifier property to its property entity | |||
BIND(IRI(REPLACE(STR(?qualProp), "prop/qualifier", "entity")) AS ?qualPropEntity) | |||
OPTIONAL { | |||
?qualPropEntity rdfs:label ?qualPropLabel . | |||
FILTER(LANG(?qualPropLabel) = "en") | |||
} | |||
OPTIONAL { | |||
?qualValue rdfs:label ?qualValueLabel . | |||
FILTER(LANG(?qualValueLabel) = "en") | |||
} | |||
} | |||
} | |||
ORDER BY ?Label | |||
]] | |||
-- Executing the SPARQL query and retrieving results in JSON format | |||
local jsonResults = sparql.runQuery(sparqlQuery) | |||
-- Validate results | |||
if not jsonResults or not jsonResults.results or not jsonResults.results.bindings then | |||
return "No specialized research fields found" | |||
end | |||
local listItems = {} | |||
-- Get the number of specialized research fields | |||
local totallistItems = #jsonResults.results.bindings | |||
-- Loop through the bindings | |||
for index = 0, totallistItems do | |||
local item = jsonResults.results.bindings[index] | |||
if not item.Label.value then | |||
return "Error: Missing item.Label.value" | |||
elseif not item.URL.value then | |||
return "Error: Missing item.URL.value" | |||
else | |||
local label = item.Label.value | |||
local url = item.URL.value | |||
local numericId = url:match("Q(%d+)") | |||
local urlRendered = "https://portal.mardi4nfdi.de/wiki/Model:" .. numericId | |||
local qualValue = item.qualValueLabel or item.qualValue or "" | |||
local qualPropLabel = item.qualPropLabel or "" | |||
local labelWithUrl = string.format('[%s %s]', tostring(url), tostring(label)) | |||
if qualValue ~= "" then | |||
local qualValueWithUrl = string.format('[%s %s]', tostring(item.qualValue.value), tostring(item.qualValueLabel.value)) | |||
local row = "| " .. labelWithUrl .. " || " .. qualPropLabel.value .. " || " .. qualValueWithUrl | |||
table.insert(listItems, row) | |||
else | |||
table.insert(listItems, "| " .. labelWithUrl) | |||
end | |||
end | |||
end | |||
-- Construct the Wikitext table | |||
local wikitextTable = "{| class='wikitable'\n" .. table.concat(listItems, "\n|-\n") .. "\n|}" | |||
return wikitextTable | |||
end | |||
-- Function to get instance of types | |||
function p.getInstanceOfTypes(frame) | |||
local entityId = frame.args[1] | |||
-- Validate input parameter | |||
if not entityId or entityId == '' then | |||
return "Error: No entity ID provided" | |||
end | |||
-- Constructing the SPARQL query with dynamic entity entityId | |||
-- P31: instance of property id | |||
local sparqlQuery = [[ | |||
PREFIX entityId: <https://portal.mardi4nfdi.de/entity/]] .. entityId .. [[> | |||
SELECT ?InstanceOfTypeLabel WHERE { | |||
entityId: p:P31 ?statement . | |||
?statement ps:P31 ?InstanceOfType . | |||
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". } | |||
} | |||
ORDER BY ?InstanceOfTypeLabel | |||
]] | |||
-- Executing the SPARQL query and retrieving results in JSON format | |||
local jsonResults = sparql.runQuery(sparqlQuery) | |||
-- Validate results | |||
if not jsonResults or not jsonResults.results or not jsonResults.results.bindings then | |||
end | |||
local InstanceOfTypes = {} | |||
-- Get the number of model types | |||
local totalInstanceOfTypes = #jsonResults.results.bindings | |||
-- Loop through the bindings | |||
for index = 0, totalInstanceOfTypes do | |||
local item = jsonResults.results.bindings[index] | |||
if item and item.InstanceOfTypeLabel and item.InstanceOfTypeLabel.value then | |||
local label = item.InstanceOfTypeLabel.value | |||
table.insert(InstanceOfTypes, label) | |||
end | |||
end | |||
-- Construct the Wikitext table | |||
local wikitextTable = "{| class='wikitable'\n|-\n| " .. table.concat(InstanceOfTypes, " || ") .. "\n|}" | |||
return wikitextTable | |||
end | |||
-- Function to get instance of types | |||
function p.getListNamedAfter(frame) | |||
local entityId = frame.args[1] | |||
-- Validate input parameter | |||
if not entityId or entityId == '' then | |||
return "Error: No entity ID provided" | |||
end | |||
-- Constructing the SPARQL query with dynamic entity entityId | |||
-- P31: instance of property id | |||
local sparqlQuery = [[ | |||
PREFIX entityId: <https://portal.mardi4nfdi.de/entity/]] .. entityId .. [[> | |||
SELECT ?namedAfterLabel ?namedAfter | |||
WHERE { | |||
entityId: p:P558 ?statement . | |||
?statement ps:P558 ?namedAfter . | |||
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". } | |||
} | |||
ORDER BY ?namedAfterLabel | |||
]] | |||
-- Executing the SPARQL query and retrieving results in JSON format | |||
local jsonResults = sparql.runQuery(sparqlQuery) | |||
-- Validate results | |||
if not jsonResults or not jsonResults.results or not jsonResults.results.bindings then | |||
end | |||
local ListNamedAfter = {} | |||
-- Get the number of persons named after | |||
local totalPersons = #jsonResults.results.bindings | |||
-- Loop through the bindings | |||
for index = 0, totalPersons do | |||
local item = jsonResults.results.bindings[index] | |||
if item and item.namedAfterLabel and item.namedAfterLabel.value then | |||
local label = item.namedAfterLabel.value | |||
local url = item.namedAfter.value | |||
local numericId = url:match("Q(%d+)") | |||
local urlRendered = "https://portal.mardi4nfdi.de/wiki/Person:" .. numericId | |||
local labelWithUrl = string.format('[%s %s]', tostring(urlRendered), tostring(label)) | |||
table.insert(ListNamedAfter, labelWithUrl) | |||
end | |||
end | |||
return table.concat(ListNamedAfter, ', ') | |||
-- end of function getListNamedAfter | |||
end | |||
return p | return p | ||
Latest revision as of 21:32, 16 December 2025
Documentation for this module may be created at Module:MathModDBHelperMethods/doc
-- Module for executing SPARQL queries
local sparql = require('SPARQL')
-- Required module containing helper methods
local helper = require('Module:HelperMethods')
-- MediaWiki library for logging and utilities
local mw = require('mw')
local json = require("mw.text")
-- Main table to hold all functions
local p = {}
-- Function to replace pattern in the comma pattern separated list
function p.replace_pattern(frame)
local input = frame.args[1] or ""
local sep = frame.args[2] or " " -- default to space if no separator given
-- Replace comma+pattern (,xxxx) with sep
local result = string.gsub(input, ",xxxx%s*", sep)
return result
end
-- Function to generate a table listing a type of individuals
-- test with =p.getList{args={'Model'}}
function p.getList(frame)
local entityType = frame.args[1] or 'Model'
local height = frame.args[2] or '400px' -- Default height if not specified
local width = frame.args[3] or '800px' -- Default width if not specified
local baseUrl = mw.site.server -- Get the current URL
-- Define mapping of entity types to their corresponding Q IDs and URL prefixes
local entityConfig = {
['Model'] = {qid = 'Q68663', urlPrefix = 'Model:', title = 'mathematical models'},
['Academic discipline'] = {qid = 'Q60231', urlPrefix = 'Academic_discipline:', title = 'academic disciplines'},
['Research problem'] = {qid = 'Q6534292', urlPrefix = 'Research_problem:', title = 'research problems'},
['Task'] = {qid = 'Q6534247', urlPrefix = 'Task:', title = 'computational tasks'},
['Quantity'] = {qid = 'Q6534237', urlPrefix = 'Quantity:', title = 'quantities'},
['Quantity kind'] = {qid = 'Q6534245', urlPrefix = 'Quantity:', title = 'quantity kind items'},
['Formula'] = {qid = 'Q6481152', urlPrefix = 'Formula:', title = 'mathematical expressions'}
}
-- Get configuration for the specified entity type
local config = entityConfig[entityType]
if not config then
return "Invalid entity type. Valid options are: Model, Academic discipline, Research problem, Task, Quantity, Quantity kind, Formula"
end
-- Q6534265 refers to MathModDB community
local sparqlQuery = [[
SELECT ?itemLabel ?modelURL ?item
WHERE {
?item wdt:P31 wd:]] .. config.qid .. [[;
wdt:P1495 wd:Q6534265 .
?item rdfs:label ?itemLabel .
FILTER(LANG(?itemLabel) = "en")
BIND(REPLACE(STR(?item), "^.*/Q", "]] .. baseUrl .. [[/wiki/]] .. config.urlPrefix .. [[") AS ?modelURL)
}
ORDER BY LCASE(?itemLabel)
]]
local jsonResults = sparql.runQuery(sparqlQuery)
-- Handle error in SPARQL query execution
if jsonResults and jsonResults.error then
mw.log("Error in SPARQL query: " .. tostring(jsonResults.error))
return nil
end
if not jsonResults then
return "Could not fetch data."
end
if helper.countElementsInBindings(jsonResults.results.bindings) == 0 then
return "No records found."
end
-- Convert the JSON results into a Lua table
local fieldOrder = {"modelURL", "itemLabel", "item"}
local dataTable = helper.convertJsonToTableOrdered(jsonResults, fieldOrder)
-- Create and return HTML table from the data
local headers = {entityType}
local htmlTable = helper.createHtmlTableWithMergedCols(dataTable, headers, {{3}})
-- Create a parent container for the table
local parentContainer = mw.html.create('div')
:addClass('parent-container')
:css('width', width)
local heading = mw.html.create('h2')
:wikitext('List of ' .. config.title)
-- Add the table and chart to the parent container
parentContainer
:node(heading)
:node(htmlTable)
return tostring(parentContainer)
end
-- Function to get linked items
function p.getLinkedItems(frame)
local entityId = frame.args[1]
-- Validate input parameter
if not entityId or entityId == '' then
return "Error: No entity ID provided"
end
local sparqlQuery = [[
PREFIX entityId: <https://portal.mardi4nfdi.de/entity/]] .. entityId .. [[>
SELECT DISTINCT ?itemLabel ?item ?propertyLabel ?property
WHERE {
# Replace with your specific entity
?itemInter ?ps entityId: .
# Convert property URL to entity-style URL
BIND(
IRI(REPLACE(STR(?ps),
"^https://portal.mardi4nfdi.de/prop/(direct|qualifier|statement)/",
"https://portal.mardi4nfdi.de/entity/"))
AS ?property
)
# Skip unwanted property
FILTER(?property != <http://schema.org/about>)
# Clean URL: keep only QID, remove /statement/ and trailing UUID
BIND(
IRI(
REPLACE(
STR(?itemInter),
".*/(Q[0-9]+).*",
"https://portal.mardi4nfdi.de/entity/$1"
)
) AS ?item
)
# Get labels
SERVICE wikibase:label {
bd:serviceParam wikibase:language "en".
?item rdfs:label ?itemLabel .
?property rdfs:label ?propertyLabel .
}
}
ORDER BY LCASE(?itemLabel)
]]
-- Executing the SPARQL query and retrieving results in JSON format
local jsonResults = sparql.runQuery(sparqlQuery)
-- Validate results
if not jsonResults or not jsonResults.results or not jsonResults.results.bindings then
return ""
end
local linkedItems = {}
local totalLinkedItems = #jsonResults.results.bindings
if totalLinkedItems >= 0 then
-- Loop through the bindings
for index = 0, totalLinkedItems do
local item = jsonResults.results.bindings[index]
if not item then
return ""
end
if not item.itemLabel or not item.itemLabel.value then
return ""
elseif not item.item or not item.item.value then
return ""
else
local itemLabel = item.itemLabel.value
local itemURL = item.item.value
local propertyLabel = item.propertyLabel and item.propertyLabel.value or ""
local propertyURL = item.property and item.property.value or ""
local itemWithURL = string.format('[%s %s]', tostring(itemURL), tostring(itemLabel))
local propertyWithURL = string.format('[%s %s]', tostring(propertyURL), tostring(propertyLabel))
table.insert(linkedItems, '| ' .. itemWithURL .. ' || ' .. propertyWithURL)
end
end
-- if there are linked items
-- Construct the Wikitext table
local wikitextTable = "{| class='wikitable'\n" ..
"! Item\n! Property\n" .. -- header row
"|-\n" .. -- separator before first data row
table.concat(linkedItems, "\n|-\n") ..
"\n|}"
return wikitextTable
else
return ""
end
end
-- Function to get subclass of items
function p.getSubclassOf(frame)
local entityId = frame.args[1]
-- Validate input parameter
if not entityId or entityId == '' then
return "Error: No entity ID provided"
end
-- Constructing the SPARQL query with dynamic entity entityId
-- P36: subclass of property id
local sparqlQuery = [[
PREFIX entityId: <https://portal.mardi4nfdi.de/entity/]] .. entityId .. [[>
SELECT ?URL ?Label
WHERE {
entityId: wdt:P36 ?URL.
?URL rdfs:label ?Label
FILTER(LANG(?Label) = "en")
}
ORDER BY ?Label
]]
-- Executing the SPARQL query and retrieving results in JSON format
local jsonResults = sparql.runQuery(sparqlQuery)
-- Validate results
if not jsonResults or not jsonResults.results or not jsonResults.results.bindings then
return "No specialized academic discipline found"
end
local subClasses = {}
-- Get the number of specialized academic disciplines
local totalSubClasses = #jsonResults.results.bindings
-- Loop through the bindings
for index = 0, totalSubClasses do
local item = jsonResults.results.bindings[index]
if not item then
return ""
end
if not item.Label.value then
return ""
elseif not item.URL.value then
return ""
else
local label = item.Label.value
local url = item.URL.value
local numericId = url:match("Q(%d+)")
local urlRendered = "https://portal.mardi4nfdi.de/wiki/Academic_discipline:" .. numericId
local labelWithUrl = string.format('[%s %s]', tostring(url), tostring(label))
table.insert(subClasses, "| " .. labelWithUrl)
end
end
-- Construct the Wikitext table
local wikitextTable = "{| class='wikitable'\n" .. table.concat(subClasses, "\n|-\n") .. "\n|}"
return wikitextTable
end
-- Function to get described by source
function p.getDescribedBySource(frame)
local entityId = frame.args[1]
-- Validate input parameter
if not entityId or entityId == '' then
return "Error: No entity ID provided"
end
-- Constructing the SPARQL query with dynamic entity entityId
-- P286: described by source property id
local sparqlQuery = [[
PREFIX entityId: <https://portal.mardi4nfdi.de/entity/]] .. entityId .. [[>
SELECT ?URL ?Label
WHERE {
entityId: wdt:P286 ?URL.
?URL rdfs:label ?Label
FILTER(LANG(?Label) = "en")
}
ORDER BY ?Label
]]
-- Executing the SPARQL query and retrieving results in JSON format
local jsonResults = sparql.runQuery(sparqlQuery)
-- Validate results
if not jsonResults or not jsonResults.results or not jsonResults.results.bindings then
return "No specialized academic discipline found"
end
local describedBySources = {}
-- Get the number of specialized academic disciplines
local totalSources = #jsonResults.results.bindings
-- Loop through the bindings
for index = 0, totalSources do
local item = jsonResults.results.bindings[index]
if not item then
return ""
end
if not item.Label.value then
return ""
elseif not item.URL.value then
return ""
else
local label = item.Label.value
local url = item.URL.value
local numericId = url:match("Q(%d+)")
local urlRendered = "https://portal.mardi4nfdi.de/wiki/Academic_discipline:" .. numericId
local labelWithUrl = string.format('[%s %s]', tostring(url), tostring(label))
table.insert(describedBySources, "| " .. labelWithUrl)
end
end
-- Construct the Wikitext table
local wikitextTable = "{| class='wikitable'\n" .. table.concat(describedBySources, "\n|-\n") .. "\n|}"
return wikitextTable
end
function p.getImageWithLegend(frame)
-- Property ID for the image
local pidImage = "P356"
-- Property ID for the (qualifier) media legend
local pidMediaLegend = "P401"
local defaultLegend = "No legend available."
local entityId = frame.args[1]
-- Validate input parameter
if not entityId or entityId == '' then
return "Error: No entity ID provided"
end
-- Attempt to retrieve entity data
local entity = mw.wikibase.getEntity(entityId)
local imageClaims = entity.claims[pidImage]
local imageStrings = {}
if imageClaims and type(imageClaims) == "table" then
local numClaims = #imageClaims
-- Loop through the image claims
-- for index = 1, numClaims do
local index = 1
for _, claim in ipairs(imageClaims) do
-- Extract the image filename
-- local imageFilename = imageClaims[index].mainsnak.datavalue.value
local imageFilename = claim.mainsnak.datavalue.value
-- Default legend (empty string)
local imageLegend = ""
-- Check if the media legend qualifier exists
if claim.qualifiers and claim.qualifiers[pidMediaLegend]
and #claim.qualifiers[pidMediaLegend] > 0
and claim.qualifiers[pidMediaLegend][1].datavalue
and claim.qualifiers[pidMediaLegend][1].datavalue.value
and claim.qualifiers[pidMediaLegend][1].datavalue.value.text then
imageLegend = claim.qualifiers[pidMediaLegend][1].datavalue.value.text
end
-- local imageLegend = imageClaims[index].qualifiers[pidMediaLegend][1].datavalue.value.text
-- Add this image line to the list
-- table.insert(imageStrings, {filename = imageFilename, legend = imageLegend})
table.insert(imageStrings, string.format("[[File:%s|thumb|380px|%s]]", imageFilename, imageLegend))
if index < numClaims then
-- spacer column
table.insert(imageStrings, ' ')
end
index = index + 1
end
-- Combine all image cells into one row of a wikitable
local imageTable = '{| class="wikitable"\n| ' .. table.concat(imageStrings, ' || ') .. '\n|}'
return imageTable .. "\n\n"
else
return ""
end
end
function p.getVideoWithLegend(frame)
-- Property ID for the video
local pidVideo = "P797"
-- Property ID for the (qualifier) media legend
local pidMediaLegend = "P401"
local defaultLegend = "No legend available."
local entityId = frame.args[1]
-- Validate input parameter
if not entityId or entityId == '' then
return "Error: No entity ID provided"
end
-- Attempt to retrieve entity data
local entity = mw.wikibase.getEntity(entityId)
local videoClaims = entity.claims[pidVideo]
local videoStrings = {}
if videoClaims and type(videoClaims) == "table" then
local numClaims = #videoClaims
-- Loop through the image claims
for index = 1, numClaims do
-- Extract the image filename
local videoFilename = videoClaims[index].mainsnak.datavalue.value
local videoLegend = videoClaims[index].qualifiers[pidMediaLegend][1].datavalue.value.text
-- Add this image line to the list
table.insert(videoStrings, string.format("[[File:%s|thumb|340px|%s]]", videoFilename, videoLegend))
if index < numClaims then
-- spacer column
table.insert(videoStrings, ' ')
end
end
-- Combine all image cells into one row of a wikitable
local videoTable = '{| class="wikitable"\n| ' .. table.concat(videoStrings, ' || ') .. '\n|}'
return videoTable .. "\n\n"
else
return " "
end
end
function p.getLocalImageWithLegend(frame)
-- Property ID for the image
local pidImage = "P1640"
-- Property ID for the (qualifier) media legend
local pidMediaLegend = "P401"
local defaultLegend = "No legend available."
local entityId = frame.args[1]
-- Validate input parameter
if not entityId or entityId == '' then
return "Error: No entity ID provided"
end
-- Attempt to retrieve entity data
local entity = mw.wikibase.getEntity(entityId)
local imageClaims = entity.claims[pidImage]
local imageStrings = {}
if imageClaims and type(imageClaims) == "table" then
local numClaims = #imageClaims
-- Loop through the image claims
for index = 1, numClaims do
-- Extract the image filename
local imageFilename = imageClaims[index].mainsnak.datavalue.value
-- Default legend (empty string)
local imageLegend = ""
-- Check if the media legend qualifier exists
if imageClaims[index].qualifiers and imageClaims[index].qualifiers[pidMediaLegend]
and #imageClaims[index].qualifiers[pidMediaLegend] > 0
and imageClaims[index].qualifiers[pidMediaLegend][1].datavalue
and imageClaims[index].qualifiers[pidMediaLegend][1].datavalue.value
and imageClaims[index].qualifiers[pidMediaLegend][1].datavalue.value.text then
imageLegend = imageClaims[index].qualifiers[pidMediaLegend][1].datavalue.value.text
end
-- Add this image line to the list
table.insert(imageStrings, string.format("[[File:%s|thumb|380px|%s]]", imageFilename, imageLegend))
if index < numClaims then
-- spacer column
table.insert(imageStrings, ' ')
end
end
-- Combine all image cells into one row of a wikitable
local imageTable = '{| class="wikitable"\n| ' .. table.concat(imageStrings, ' || ') .. '\n|}'
return imageTable .. "\n\n"
else
return " "
end
end
function p.getLocalVideoWithLegend(frame)
-- Property ID for the video
local pidVideo = "P1675"
-- Property ID for the (qualifier) media legend
local pidMediaLegend = "P401"
local defaultLegend = "No legend available."
local entityId = frame.args[1]
-- Validate input parameter
if not entityId or entityId == '' then
return "Error: No entity ID provided"
end
-- Attempt to retrieve entity data
local entity = mw.wikibase.getEntity(entityId)
local videoClaims = entity.claims[pidVideo]
local videoStrings = {}
if videoClaims and type(videoClaims) == "table" then
local numClaims = #videoClaims
-- Loop through the image claims
for index = 1, numClaims do
-- Extract the image filename
local videoFilename = videoClaims[index].mainsnak.datavalue.value
local videoLegend = videoClaims[index].qualifiers[pidMediaLegend][1].datavalue.value.text
-- Add this image line to the list
table.insert(videoStrings, string.format("[[File:%s|thumb|340px|%s]]", videoFilename, videoLegend))
if index < numClaims then
-- spacer column
table.insert(videoStrings, ' ')
end
end
-- Combine all image cells into one row of a wikitable
local videoTable = '{| class="wikitable"\n| ' .. table.concat(videoStrings, ' || ') .. '\n|}'
return videoTable .. "\n\n"
else
return " "
end
end
-- Function to get list with qualifier values only
function p.getListWithQualifierValues(frame)
local entityId = frame.args[1]
local propertyId = frame.args[2]
-- Validate input parameter
if not entityId or entityId == '' then
return " "
end
-- Constructing the SPARQL query with dynamic entity entityId
local sparqlQuery = [[
PREFIX entityId: <https://portal.mardi4nfdi.de/entity/]] .. entityId .. [[>
SELECT ?URL ?Label ?qualPropEntity ?qualPropLabel ?qualValue ?qualValueLabel
WHERE {
entityId: p:]] .. propertyId .. [[ ?statement .
?statement ps:]] .. propertyId .. [[ ?URL .
?URL rdfs:label ?Label
FILTER(LANG(?Label) = "en")
OPTIONAL {
?statement ?qualProp ?qualValue .
FILTER(STRSTARTS(STR(?qualProp), STR(pq:))) # only qualifiers
# Map qualifier property to its property entity
BIND(IRI(REPLACE(STR(?qualProp), "prop/qualifier", "entity")) AS ?qualPropEntity)
OPTIONAL {
?qualPropEntity rdfs:label ?qualPropLabel .
FILTER(LANG(?qualPropLabel) = "en")
}
OPTIONAL {
?qualValue rdfs:label ?qualValueLabel .
FILTER(LANG(?qualValueLabel) = "en")
}
}
}
ORDER BY ?Label
]]
-- Executing the SPARQL query and retrieving results in JSON format
local jsonResults = sparql.runQuery(sparqlQuery)
-- Validate results
if not jsonResults or not jsonResults.results or not jsonResults.results.bindings then
return "No specialized research fields found"
end
local listItems = {}
-- Get the number of specialized research fields
local totallistItems = #jsonResults.results.bindings
-- Loop through the bindings
for index = 0, totallistItems do
local item = jsonResults.results.bindings[index]
if not item.Label.value then
return "Error: Missing item.Label.value"
elseif not item.URL.value then
return "Error: Missing item.URL.value"
else
local label = item.Label.value
local url = item.URL.value
local numericId = url:match("Q(%d+)")
local urlRendered = "https://portal.mardi4nfdi.de/wiki/Model:" .. numericId
local qualValue = item.qualValueLabel or item.qualValue or ""
local labelWithUrl = string.format('[%s %s]', tostring(url), tostring(label))
if qualValue ~= "" then
local qualValueWithUrl = string.format('[%s %s]', tostring(item.qualValue.value), tostring(item.qualValueLabel.value))
local row = "| " .. labelWithUrl .. " || (" .. qualValueWithUrl .. ")"
table.insert(listItems, row)
else
table.insert(listItems, "| " .. labelWithUrl)
end
end
end
-- Construct the Wikitext table
local wikitextTable = "{| class='wikitable'\n" .. table.concat(listItems, "\n|-\n") .. "\n|}"
return wikitextTable
end
-- Function to get list with qualifier values and qualifier labels
function p.getListWithQualifierValuesLabels(frame)
local entityId = frame.args[1]
local propertyId = frame.args[2]
-- Validate input parameter
if not entityId or entityId == '' then
return " "
end
-- Constructing the SPARQL query with dynamic entity entityId
local sparqlQuery = [[
PREFIX entityId: <https://portal.mardi4nfdi.de/entity/]] .. entityId .. [[>
SELECT ?URL ?Label ?qualPropEntity ?qualPropLabel ?qualValue ?qualValueLabel
WHERE {
entityId: p:]] .. propertyId .. [[ ?statement .
?statement ps:]] .. propertyId .. [[ ?URL .
?URL rdfs:label ?Label
FILTER(LANG(?Label) = "en")
OPTIONAL {
?statement ?qualProp ?qualValue .
FILTER(STRSTARTS(STR(?qualProp), STR(pq:))) # only qualifiers
# Map qualifier property to its property entity
BIND(IRI(REPLACE(STR(?qualProp), "prop/qualifier", "entity")) AS ?qualPropEntity)
OPTIONAL {
?qualPropEntity rdfs:label ?qualPropLabel .
FILTER(LANG(?qualPropLabel) = "en")
}
OPTIONAL {
?qualValue rdfs:label ?qualValueLabel .
FILTER(LANG(?qualValueLabel) = "en")
}
}
}
ORDER BY ?Label
]]
-- Executing the SPARQL query and retrieving results in JSON format
local jsonResults = sparql.runQuery(sparqlQuery)
-- Validate results
if not jsonResults or not jsonResults.results or not jsonResults.results.bindings then
return "No specialized research fields found"
end
local listItems = {}
-- Get the number of specialized research fields
local totallistItems = #jsonResults.results.bindings
-- Loop through the bindings
for index = 0, totallistItems do
local item = jsonResults.results.bindings[index]
if not item.Label.value then
return "Error: Missing item.Label.value"
elseif not item.URL.value then
return "Error: Missing item.URL.value"
else
local label = item.Label.value
local url = item.URL.value
local numericId = url:match("Q(%d+)")
local urlRendered = "https://portal.mardi4nfdi.de/wiki/Model:" .. numericId
local qualValue = item.qualValueLabel or item.qualValue or ""
local qualPropLabel = item.qualPropLabel or ""
local labelWithUrl = string.format('[%s %s]', tostring(url), tostring(label))
if qualValue ~= "" then
local qualValueWithUrl = string.format('[%s %s]', tostring(item.qualValue.value), tostring(item.qualValueLabel.value))
local row = "| " .. labelWithUrl .. " || " .. qualPropLabel.value .. " || " .. qualValueWithUrl
table.insert(listItems, row)
else
table.insert(listItems, "| " .. labelWithUrl)
end
end
end
-- Construct the Wikitext table
local wikitextTable = "{| class='wikitable'\n" .. table.concat(listItems, "\n|-\n") .. "\n|}"
return wikitextTable
end
-- Function to get instance of types
function p.getInstanceOfTypes(frame)
local entityId = frame.args[1]
-- Validate input parameter
if not entityId or entityId == '' then
return "Error: No entity ID provided"
end
-- Constructing the SPARQL query with dynamic entity entityId
-- P31: instance of property id
local sparqlQuery = [[
PREFIX entityId: <https://portal.mardi4nfdi.de/entity/]] .. entityId .. [[>
SELECT ?InstanceOfTypeLabel WHERE {
entityId: p:P31 ?statement .
?statement ps:P31 ?InstanceOfType .
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
ORDER BY ?InstanceOfTypeLabel
]]
-- Executing the SPARQL query and retrieving results in JSON format
local jsonResults = sparql.runQuery(sparqlQuery)
-- Validate results
if not jsonResults or not jsonResults.results or not jsonResults.results.bindings then
end
local InstanceOfTypes = {}
-- Get the number of model types
local totalInstanceOfTypes = #jsonResults.results.bindings
-- Loop through the bindings
for index = 0, totalInstanceOfTypes do
local item = jsonResults.results.bindings[index]
if item and item.InstanceOfTypeLabel and item.InstanceOfTypeLabel.value then
local label = item.InstanceOfTypeLabel.value
table.insert(InstanceOfTypes, label)
end
end
-- Construct the Wikitext table
local wikitextTable = "{| class='wikitable'\n|-\n| " .. table.concat(InstanceOfTypes, " || ") .. "\n|}"
return wikitextTable
end
-- Function to get instance of types
function p.getListNamedAfter(frame)
local entityId = frame.args[1]
-- Validate input parameter
if not entityId or entityId == '' then
return "Error: No entity ID provided"
end
-- Constructing the SPARQL query with dynamic entity entityId
-- P31: instance of property id
local sparqlQuery = [[
PREFIX entityId: <https://portal.mardi4nfdi.de/entity/]] .. entityId .. [[>
SELECT ?namedAfterLabel ?namedAfter
WHERE {
entityId: p:P558 ?statement .
?statement ps:P558 ?namedAfter .
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
ORDER BY ?namedAfterLabel
]]
-- Executing the SPARQL query and retrieving results in JSON format
local jsonResults = sparql.runQuery(sparqlQuery)
-- Validate results
if not jsonResults or not jsonResults.results or not jsonResults.results.bindings then
end
local ListNamedAfter = {}
-- Get the number of persons named after
local totalPersons = #jsonResults.results.bindings
-- Loop through the bindings
for index = 0, totalPersons do
local item = jsonResults.results.bindings[index]
if item and item.namedAfterLabel and item.namedAfterLabel.value then
local label = item.namedAfterLabel.value
local url = item.namedAfter.value
local numericId = url:match("Q(%d+)")
local urlRendered = "https://portal.mardi4nfdi.de/wiki/Person:" .. numericId
local labelWithUrl = string.format('[%s %s]', tostring(urlRendered), tostring(label))
table.insert(ListNamedAfter, labelWithUrl)
end
end
return table.concat(ListNamedAfter, ', ')
-- end of function getListNamedAfter
end
return p