Module:MwJson: Difference between revisions

From Battery Knowledge Base
Update package: OSW Core
(Update package: OSW Core)
Tag: Manual revert
(Update package: OSW Core)
Tag: Reverted
Line 23: Line 23:
}  
}  
p.slots = { --slot names
p.slots = { --slot names
main='main',
jsondata='jsondata',  
jsondata='jsondata',  
jsonschema='jsonschema',  
jsonschema='jsonschema',  
Line 34: Line 35:
query='query'
query='query'
}
}
p.cache = {}


--loads json from a wiki page
--loads json from a wiki page
Line 40: Line 43:
function p.loadJson(args)
function p.loadJson(args)
local page_title = p.defaultArg(args.title, "JsonSchema:Entity") --for testing
local page_title = p.defaultArg(args.title, "JsonSchema:Entity") --for testing
local slot = p.defaultArg(args.slot, nil)
local slot = p.defaultArg(args.slot, 'main')
local debug = p.defaultArg(args.debug, nil)
local debug = p.defaultArg(args.debug, nil)
local msg = ""
local msg = ""
Line 46: Line 49:
local json = {}
local json = {}
if (slot == nil) then
if p.cache[page_title] ~= nil then
if p.cache[page_title][slot] ~= nil then
if (debug) then msg = msg .. "Fetch slot " .. p.slots.jsondata .. " of page " .. page_title .. " from cache <br>" end
json = p.cache[page_title][slot]
return {json=json, debug_msg=msg}
end
else p.cache[page_title] = {}
end
if (slot == 'main') then
--json = mw.loadJsonData( "JsonSchema:Entity" ) --requires MediaWiki 1.39
--json = mw.loadJsonData( "JsonSchema:Entity" ) --requires MediaWiki 1.39
local page = mw.title.makeTitle(p.splitString(page_title, ':')[1], p.splitString(page_title, ':')[2])
local page = mw.title.makeTitle(p.splitString(page_title, ':')[1], p.splitString(page_title, ':')[2])
Line 52: Line 64:
if (text ~= nil) then json = mw.text.jsonDecode(text) end
if (text ~= nil) then json = mw.text.jsonDecode(text) end
else
else
if (debug) then msg = msg .. "Fetch slot " .. p.slots.jsondata .. " from page " .. title .. "<br>" end
if (debug) then msg = msg .. "Fetch slot " .. p.slots.jsondata .. " of page " .. page_title .. "<br>" end
local text = mw.slots.slotContent( slot , page_title )
local text = mw.slots.slotContent( slot , page_title )
if (text ~= nil) then json = mw.text.jsonDecode(text) end
if (text ~= nil) then json = mw.text.jsonDecode(text) end
Line 58: Line 70:
--mw.logObject(json)
--mw.logObject(json)
p.cache[page_title][slot] = json


return {json=json, debug_msg=msg}
return {json=json, debug_msg=msg}
end
end


-- test: mw.logObject(p.walkJsonSchema({jsonschema=p.loadJson({title="Category:Hardware", slot="jsonschema"}).json, debug=true}).jsonschema)
-- test: mw.logObject(p.walkJsonSchema({jsonschema=p.loadJson({title="Category:Hardware", slot="jsonschema"}).json, debug=true}).jsonschema)
Line 302: Line 316:
-- store metadata where properties were defined / overridden
-- store metadata where properties were defined / overridden
for i, category in ipairs(schema_res.visited) do  
for i, category in ipairs(schema_res.visited) do  
for k, v in pairs(schema_res.jsonschemas[category]['properties']) do
for k, v in pairs(p.defaultArgPath(schema_res.jsonschemas, {category, 'properties'}, {})) do --property section may not exisit
if smw_res.definitions[k] == nil then smw_res.definitions[k] = {} end
if smw_res.definitions[k] == nil then smw_res.definitions[k] = {} end
if smw_res.definitions[k]['defined_in'] == nil then smw_res.definitions[k]['defined_in'] = {} end
if smw_res.definitions[k]['defined_in'] == nil then smw_res.definitions[k]['defined_in'] = {} end
Line 348: Line 362:
if j > i then
if j > i then
local subjsonschema = schema_res.jsonschemas[subcategory]
local subjsonschema = schema_res.jsonschemas[subcategory]
for k, v in pairs(subjsonschema['properties']) do
for k, v in pairs(p.defaultArg(subjsonschema['properties'], {})) do
-- skip properties that are overwritten in subschemas, render them only once at the most specific position
-- skip properties that are overwritten in subschemas, render them only once at the most specific position
ignore_properties[k] = true
ignore_properties[k] = true
Line 372: Line 386:
-- Todo: Consider moving the category and this block to p.getSemanticProperties with store=true. However, settings categories with @category is only possible for subobjects
-- Todo: Consider moving the category and this block to p.getSemanticProperties with store=true. However, settings categories with @category is only possible for subobjects
if (smw_res ~= nil) then
if (smw_res ~= nil) then
local display_label = p.getDisplayLabel(jsondata, smw_res.properties)
if title.nsText == "Property" then display_label = p.defaultArgPath(jsondata, {p.keys.name}, display_label) end
if (debug) then msg = msg .. "Store page properties" end
if (debug) then msg = msg .. "Store page properties" end
-- category handling
-- category handling
Line 380: Line 397:
-- label and display title handling
-- label and display title handling
smw_res.properties['Display title of'] = display_label --set special property display title
if display_label ~= nil then
smw_res.properties['Display title of lowercase'] = display_label:lower() --store lowercase for case insensitive query
smw_res.properties['Display title of'] = display_label --set special property display title
smw_res.properties['Display title of normalized'] = display_label:lower():gsub('[^%w]+','') --store with all non-alphanumeric chars removed for normalized query
smw_res.properties['Display title of lowercase'] = display_label:lower() --store lowercase for case insensitive query
smw_res.properties['Display title of normalized'] = display_label:lower():gsub('[^%w]+','') --store with all non-alphanumeric chars removed for normalized query
end
p.setNormalizedLabel(smw_res.properties) --build normalized multilang label
p.setNormalizedLabel(smw_res.properties) --build normalized multilang label
mw.ext.displaytitle.set(display_label)
mw.ext.displaytitle.set(display_label)
Line 417: Line 436:
local ignore_properties = p.defaultArg(args.ignore_properties, {})
local ignore_properties = p.defaultArg(args.ignore_properties, {})


local schema_label = ""
local schema_label = p.renderMultilangValue({jsonschema=schema})
if schema['title'] ~= nil then schema_label = schema['title'] end
-- see also: https://help.fandom.com/wiki/Extension:Scribunto/HTML_Library_usage_notes
-- see also: https://help.fandom.com/wiki/Extension:Scribunto/HTML_Library_usage_notes
Line 435: Line 453:
--mw.logObject(def)
--mw.logObject(def)
local label = k
local label = p.renderMultilangValue({jsonschema=def, default=k})
if def['title'] ~= nil then label = def['title'] end
if def['title*'] ~= nil then -- multilang label with switch
label = "{{#switch:{{USERLANGUAGECODE}} |#default=" ..  label
for k,v in pairs(def['title*']) do label = label .. " |" .. k .. "=" .. v end
label = label .. " }}"
end
local description = ""
local description = p.renderMultilangValue({jsonschema=def, key="description"})
if def['description'] ~= nil then description = def['description'] end
if def['description*'] ~= nil then -- multilang label with switch
description = "{{#switch:{{USERLANGUAGECODE}} |#default=" ..  description
for k,v in pairs(def['description*']) do description = description .. " |" .. k .. "=" .. v end
description = description .. " }}"
end
if (p.tableLength(p.defaultArgPath(property_definitions, {k, 'defined_in'}, {})) > 0) then description = description .. "<br>Definition: " end
if (p.tableLength(p.defaultArgPath(property_definitions, {k, 'defined_in'}, {})) > 0) then description = description .. "<br>Definition: " end
for i, c in pairs(p.defaultArgPath(property_definitions, {k, 'defined_in'}, {})) do  
for i, c in pairs(p.defaultArgPath(property_definitions, {k, 'defined_in'}, {})) do  
Line 484: Line 490:
elseif (type(v) == 'boolean') then  
elseif (type(v) == 'boolean') then  
if (v) then v = "&#x2705;" else v = "&#x274C;" end -- green check mark or red cross
if (v) then v = "&#x2705;" else v = "&#x274C;" end -- green check mark or red cross
elseif ((string.len(e) > 100) and (string.find(e, "{{") == nil) and (string.find(e, "</") == nil)) then  
elseif (def['eval_template'] == nil and (string.len(e) > 100) and (string.find(e, "{{") == nil) and (string.find(e, "</") == nil) and (string.find(e, "%[%[") == nil)) then -- no markup, no links
e = string.sub(e, 1, 100) .. "..."; -- limit infobox plain text to max 100 chars
e = string.sub(e, 1, 100) .. "..."; -- limit infobox plain text to max 100 chars
elseif (debug) then
elseif (debug) then
Line 511: Line 517:
elseif (type(v) == 'boolean') then  
elseif (type(v) == 'boolean') then  
if (v) then v = "&#x2705;" else v = "&#x274C;" end -- green check mark or red cross
if (v) then v = "&#x2705;" else v = "&#x274C;" end -- green check mark or red cross
elseif ((string.len(v) > 100) and (string.find(v, "{{") == nil) and (string.find(v, "</") == nil)) then
elseif (def['eval_template'] == nil and (string.len(v) > 100) and (string.find(v, "{{") == nil) and (string.find(v, "</") == nil) and (string.find(v, "%[%[") == nil)) then -- no markup, no links
v = string.sub(v, 1, 100) .. "..."; -- limit infobox plain text to max 100 chars
v = string.sub(v, 1, 100) .. "..."; -- limit infobox plain text to max 100 chars
elseif (debug) then
elseif (debug) then
Line 790: Line 796:
p.tableMerge(properties['@category'], properties[p.keys.category_pseudoproperty]) -- from json-ld context 'Property:Category'
p.tableMerge(properties['@category'], properties[p.keys.category_pseudoproperty]) -- from json-ld context 'Property:Category'
properties[p.keys.category_pseudoproperty] = nil -- delete pseudo property
properties[p.keys.category_pseudoproperty] = nil -- delete pseudo property
if (jsondata[p.keys.name] ~= nil) then properties['Display title of'] = jsondata[p.keys.name]  
elseif (jsondata[p.keys.label] ~= nil and jsondata[p.keys.label][1] ~= nil) then properties['Display title of'] = p.splitString(jsondata[p.keys.label][1], '@')[1]
local display_label = p.getDisplayLabel(jsondata, properties)
else properties['Display title of'] = p.defaultArg(subschema['title'], "") end
if properties['Display title of'] == nil and properties['Display_title_of'] == nil then
if (display_label ~= nil and display_label ~= "") then properties['Display title of'] = display_label
else properties['Display title of'] = p.defaultArg(subschema['title'], "") end -- fall back to property name in schema
end
p.setNormalizedLabel(properties) --build normalized multilang label
p.setNormalizedLabel(properties) --build normalized multilang label
if (p.tableLength(properties) > 0) then
if (p.tableLength(properties) > 0) then
Line 1,032: Line 1,041:
   for k, v in pairs(obj) do res[p.copy(k, s)] = p.copy(v, s) end
   for k, v in pairs(obj) do res[p.copy(k, s)] = p.copy(v, s) end
   return res
   return res
end
-- get normalized label
function p.getDisplayLabel(jsondata, properties)
local display_label = nil
-- check if label properties are mapped
if (properties["HasLabel"] ~= nil and properties["HasLabel"][1] ~= nil) then display_label = p.splitString(properties["HasLabel"][1], '@')[1]
elseif (properties["HasName"] ~= nil) then
if type(properties["HasName"]) == 'table' then display_label = properties["HasName"][1]
else display_label = properties["HasName"] end
-- fall back to unmapped keywords
elseif (jsondata[p.keys.label] ~= nil and jsondata[p.keys.label][1] ~= nil) then display_label = p.splitString(jsondata[p.keys.label][1], '@')[1]
elseif (jsondata[p.keys.name] ~= nil) then display_label = jsondata[p.keys.name]
end
return display_label
end
end


Line 1,065: Line 1,090:
end
end
end
end
end
function p.renderMultilangValue(args)
local jsondata = p.defaultArg(args.jsondata, {})
local jsonschema = p.defaultArg(args.jsonschema, {})
local key = p.defaultArg(args.key, "title")
local result = p.defaultArg(args.default, "")
local default = p.defaultArg(args.default, nil)
-- "title*": {"de": ...}
if jsonschema[key] ~= nil then result = jsonschema[key] end
if jsonschema[key .. '*'] ~= nil then -- multilang label with switch
result = "{{#switch:{{USERLANGUAGECODE}} |#default=" ..  result
for k,v in pairs(jsonschema[key .. '*']) do
if k == en then default = v
else result = result .. " |" .. k .. "=" .. v end
end
if default ~= nil then result = result .. " |#default=" ..  default end
result = result .. " }}"
end
-- "some_property": [{"lang": "de", "text": ...}]
if jsondata[key] ~= nil then -- multilang label with switch
result = "{{#switch:{{USERLANGUAGECODE}}"
for k,v in pairs(jsondata[key]) do
if v["lang"] ~= nil and v["text"] ~= nil then
if v["lang"] == "en" then default = v["text"]
else result = result .. " |" .. v["lang"] .. "=" .. v["text"] end
end
end
if default ~= nil then result = result .. " |#default=" ..  default end
result = result .. " }}"
end
return result
end
end


return p
return p
Cookies help us deliver our services. By using our services, you agree to our use of cookies.