472
edits
(import from wiki-dev) |
(Update package: OSW Core) Tags: Manual revert Reverted |
||
Line 23: | Line 23: | ||
} | } | ||
p.slots = { --slot names | p.slots = { --slot names | ||
jsondata='jsondata', | jsondata='jsondata', | ||
jsonschema='jsonschema', | jsonschema='jsonschema', | ||
Line 35: | Line 34: | ||
query='query' | query='query' | ||
} | } | ||
--loads json from a wiki page | --loads json from a wiki page | ||
Line 43: | Line 40: | ||
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, | local slot = p.defaultArg(args.slot, nil) | ||
local debug = p.defaultArg(args.debug, nil) | local debug = p.defaultArg(args.debug, nil) | ||
local msg = "" | local msg = "" | ||
Line 49: | Line 46: | ||
local json = {} | local json = {} | ||
if (slot == nil) then | |||
if (slot == | |||
--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 64: | Line 52: | ||
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 .. " | if (debug) then msg = msg .. "Fetch slot " .. p.slots.jsondata .. " from 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 | ||
end | end | ||
--mw.logObject(json) | --mw.logObject(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 122: | Line 70: | ||
local mode = p.defaultArg(args.mode, p.mode.header) | local mode = p.defaultArg(args.mode, p.mode.header) | ||
--local merged_jsonschema = p.defaultArg(args.merged_jsonschema, {}) | --local merged_jsonschema = p.defaultArg(args.merged_jsonschema, {}) | ||
local templates = p.defaultArg(args.templates, {}) | local templates = p.defaultArg(args.templates, {}) | ||
local recursive = p.defaultArg(args.recursive, true) | local recursive = p.defaultArg(args.recursive, true) | ||
Line 134: | Line 81: | ||
if (mode == p.mode.header) then category_template_slot = p.slots.header_template end | if (mode == p.mode.header) then category_template_slot = p.slots.header_template end | ||
if (categories == nil) then categories = p.getCategories({jsonschema=jsonschema, includeNamespace | if (categories == nil) then categories = p.getCategories({jsonschema=jsonschema, includeNamespace=true}).categories end | ||
if (type(categories) ~= 'table') then categories = {categories} end | if (type(categories) ~= 'table') then categories = {categories} end | ||
if (debug) then msg = msg .. "Supercategories: " .. mw.dumpObject(categories) .. "\n<br>" end | if (debug) then msg = msg .. "Supercategories: " .. mw.dumpObject(categories) .. "\n<br>" end | ||
Line 141: | Line 88: | ||
--mw.logObject("Visit " .. category) | --mw.logObject("Visit " .. category) | ||
if (debug) then msg = msg .. "Fetch slot " .. p.slots.jsonschema .. " from page " .. category .. "\n<br>" end | if (debug) then msg = msg .. "Fetch slot " .. p.slots.jsonschema .. " from page " .. category .. "\n<br>" end | ||
local | local super_jsonschema_str = mw.slots.slotContent( p.slots.jsonschema , category ) | ||
if (super_jsonschema_str ~= nil) then | |||
super_jsonschema = mw.text.jsonDecode( super_jsonschema_str ) | |||
if (recursive) then | if (recursive) then | ||
local res = p.walkJsonSchema({jsonschema=super_jsonschema, jsonschemas=jsonschemas, templates=templates, mode=mode, visited=visited, root=false}) | local res = p.walkJsonSchema({jsonschema=super_jsonschema, jsonschemas=jsonschemas, templates=templates, mode=mode, visited=visited, root=false}) | ||
Line 155: | Line 99: | ||
--mw.logObject("Store " .. category) | --mw.logObject("Store " .. category) | ||
table.insert(visited, category) | table.insert(visited, category) | ||
jsonschemas[category] = mw.text.jsonDecode( super_jsonschema_str ) --keep a copy of the schema, super_jsonschema passed by references gets modified | |||
jsonschemas[category] = | |||
--jsonschema = p.tableMerge(jsonschema, super_jsonschema) --merge superschema is done by the caller | --jsonschema = p.tableMerge(jsonschema, super_jsonschema) --merge superschema is done by the caller | ||
end | end | ||
Line 164: | Line 107: | ||
end | end | ||
end | end | ||
if (root) then | if (root) then | ||
for i, category in ipairs(visited) do | for i, category in ipairs(visited) do | ||
Line 199: | Line 137: | ||
local msg = "" | local msg = "" | ||
local res = p.defaultArg(args.jsondata, "") | local res = p.defaultArg(args.jsondata, "") | ||
for k,v in pairs(jsondata) do | for k,v in pairs(jsondata) do | ||
Line 223: | Line 160: | ||
end | end | ||
elseif type(v) == 'table' then | elseif type(v) == 'table' then | ||
if | if (v[1] == nil) then --key value array = object/dict | ||
local sub_res = p.expandEmbeddedTemplates({frame=frame, jsondata=v, jsonschema=p.defaultArgPath(jsonschema, {"properties", k}, {}), template=eval_template, mode=mode, stringify_arrays=stringify_arrays | local sub_res = p.expandEmbeddedTemplates({frame=frame, jsondata=v, jsonschema=p.defaultArgPath(jsonschema, {"properties", k}, {}), template=eval_template, mode=mode, stringify_arrays=stringify_arrays}) | ||
msg = msg .. sub_res.debug_msg | msg = msg .. sub_res.debug_msg | ||
jsondata[k] = sub_res.res | jsondata[k] = sub_res.res | ||
Line 244: | Line 181: | ||
if type(e) == 'table' then | if type(e) == 'table' then | ||
local sub_res = p.expandEmbeddedTemplates({frame=frame, jsondata=e, jsonschema=p.defaultArgPath(jsonschema, {"properties", k, "items"}, {}), template=eval_template, mode=mode, stringify_arrays=stringify_arrays | local sub_res = p.expandEmbeddedTemplates({frame=frame, jsondata=e, jsonschema=p.defaultArgPath(jsonschema, {"properties", k, "items"}, {}), template=eval_template, mode=mode, stringify_arrays=stringify_arrays}) | ||
msg = msg .. sub_res.debug_msg | msg = msg .. sub_res.debug_msg | ||
if (type(sub_res.res) == 'table') then | if (type(sub_res.res) == 'table') then | ||
Line 256: | Line 193: | ||
--evaluate single array item string as json {"self": "<value>", ".": "<value>"} => does not work since jsondata is an object | --evaluate single array item string as json {"self": "<value>", ".": "<value>"} => does not work since jsondata is an object | ||
--e = p.expandEmbeddedTemplates({frame=frame, jsondata={["self"]=e,["."]=e}, jsonschema=p.defaultArgPath(jsonschema, {"properties", k, "items"}, {}), template=eval_template, mode=mode, stringify_arrays=stringify_arrays | --e = p.expandEmbeddedTemplates({frame=frame, jsondata={["self"]=e,["."]=e}, jsonschema=p.defaultArgPath(jsonschema, {"properties", k, "items"}, {}), template=eval_template, mode=mode, stringify_arrays=stringify_arrays}) | ||
Line 279: | Line 216: | ||
if (template == nil | if (template == nil) then | ||
local templates = jsondata[p.keys.template] | local templates = jsondata[p.keys.template] | ||
if (templates == nil) then templates = p.defaultArg(jsonschema[p.keys.template], {}) end | if (templates == nil) then templates = p.defaultArg(jsonschema[p.keys.template], {}) end | ||
Line 291: | Line 228: | ||
end | end | ||
if | if template ~= nil then | ||
if (template.type == "wikitext") then | if (template.type == "wikitext") then | ||
for k,v in pairs(jsondata) do | for k,v in pairs(jsondata) do | ||
Line 339: | Line 276: | ||
if (not p.nilOrEmpty(jsondata[p.keys.category])) then categories = jsondata[p.keys.category] end -- let json property overwrite function param | if (not p.nilOrEmpty(jsondata[p.keys.category])) then categories = jsondata[p.keys.category] end -- let json property overwrite function param | ||
local schema_res = p.walkJsonSchema({jsonschema=jsonschema | local schema_res = p.walkJsonSchema({jsonschema=jsonschema, categories=categories, mode=mode, recursive=recursive, debug=debug}) | ||
local expand_res = p.expandJsonRef({json=schema_res.jsonschema, debug=debug}) | local expand_res = p.expandJsonRef({json=schema_res.jsonschema, debug=debug}) | ||
jsonschema = expand_res.json | jsonschema = expand_res.json | ||
--mw.log(mw.text.jsonEncode(jsonschema)) | --mw.log(mw.text.jsonEncode(jsonschema)) | ||
local display_label = p.defaultArgPath(jsondata, {p.keys.name}, "") | |||
if (display_label == "" or (title.nsText ~= "Category" and title.nsText ~= "Property")) then | |||
display_label = p.defaultArgPath(jsondata, {p.keys.label, 1, p.keys.text}, "") --prefere label for all non-category and non-property pages | |||
end | |||
local jsonld = p.copy(jsondata) | local jsonld = p.copy(jsondata) | ||
Line 349: | Line 291: | ||
json_res_store = p.expandEmbeddedTemplates({jsonschema=jsonschema, jsondata=json_data_store, mode='store'}) | json_res_store = p.expandEmbeddedTemplates({jsonschema=jsonschema, jsondata=json_data_store, mode='store'}) | ||
msg = msg .. json_res_store.debug_msg | msg = msg .. json_res_store.debug_msg | ||
mw.log("JSONDATA STORE") | --mw.log("JSONDATA STORE") | ||
mw.logObject(json_res_store.res) | --mw.logObject(json_res_store.res) | ||
local smw_res = nil | local smw_res = nil | ||
Line 360: | Line 302: | ||
-- 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 | for k, v in pairs(schema_res.jsonschemas[category]['properties']) do | ||
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 378: | Line 320: | ||
end | end | ||
end | end | ||
wikitext = wikitext .. "<div class='jsonld-header' style='display:none' data-jsonld='" .. mw.text.jsonEncode( jsonld ):gsub("'","`") .. "'></div>" | |||
end | end | ||
Line 420: | Line 362: | ||
end | end | ||
--local display_label = "" | |||
--if (jsondata[p.keys.label] ~= nil) then display_label = p.splitString(jsondata[p.keys.label], '@')[1] end | |||
local set_categories_in_wikitext = {} | local set_categories_in_wikitext = {} | ||
p.tableMerge(set_categories_in_wikitext, json_res_store.res[p.keys.subcategory]) --classes/categories, nil for items | p.tableMerge(set_categories_in_wikitext, json_res_store.res[p.keys.subcategory]) --classes/categories, nil for items | ||
Line 425: | Line 369: | ||
p.tableMerge(set_categories_in_wikitext, json_res_store.res[p.keys.category]) -- categories from schema type | p.tableMerge(set_categories_in_wikitext, json_res_store.res[p.keys.category]) -- categories from schema type | ||
end | end | ||
-- 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 | ||
if (debug) then msg = msg .. "Store page properties" end | if (debug) then msg = msg .. "Store page properties" end | ||
-- category handling | -- category handling | ||
Line 441: | Line 380: | ||
-- label and display title handling | -- label and display title handling | ||
smw_res.properties['Display title of'] = display_label --set special property display title | |||
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 | |||
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 547: | Line 484: | ||
elseif (type(v) == 'boolean') then | elseif (type(v) == 'boolean') then | ||
if (v) then v = "✅" else v = "❌" end -- green check mark or red cross | if (v) then v = "✅" else v = "❌" end -- green check mark or red cross | ||
elseif ((string.len(e) > 100) and (string.find(e, "{{") == nil) and (string.find(e, "</ | elseif ((string.len(e) > 100) and (string.find(e, "{{") == nil) and (string.find(e, "</") == nil)) then | ||
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 574: | Line 511: | ||
elseif (type(v) == 'boolean') then | elseif (type(v) == 'boolean') then | ||
if (v) then v = "✅" else v = "❌" end -- green check mark or red cross | if (v) then v = "✅" else v = "❌" end -- green check mark or red cross | ||
elseif ((string.len(v) > 100) and (string.find(v, "{{") == nil) and (string.find(v, "</ | elseif ((string.len(v) > 100) and (string.find(v, "{{") == nil) and (string.find(v, "</") == nil)) then | ||
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 597: | Line 534: | ||
local jsonschema = p.defaultArg(args.jsonschema, {}) | local jsonschema = p.defaultArg(args.jsonschema, {}) | ||
local includeNamespace = p.defaultArg(args.includeNamespace, false) | local includeNamespace = p.defaultArg(args.includeNamespace, false) | ||
local categories = {} | local categories = {} | ||
Line 604: | Line 540: | ||
--properties['@category'] = {} | --properties['@category'] = {} | ||
for k, entry in pairs(allOf) do | for k, entry in pairs(allOf) do | ||
if type(entry) == 'table' then -- "allOf": [{"$ref": "/wiki/Category:Test?action=raw"}] | |||
if type(entry) == 'table' then | for p, v in pairs(entry) do | ||
if (p == '$ref') then | |||
for category in v:gmatch("Category:([^?]+)") do -- e.g. "/wiki/Category:Test?action=raw" | |||
if (includeNamespace) then category = "Category:" .. category end | |||
table.insert(categories, category) | |||
end | end | ||
end | end | ||
end | end | ||
else -- "allOf": {"$ref": "/wiki/Category:Test?action=raw"} | |||
if (k == '$ref') then | |||
for category in entry:gmatch("Category:([^?]+)") do -- e.g. "/wiki/Category:Test?action=raw" | |||
if (includeNamespace) then category = "Category:" .. category end | |||
table.insert(categories, category) | |||
end | |||
end | |||
end | end | ||
end | end | ||
Line 803: | Line 739: | ||
context = p.tableMerge(context, subcontext) -- pull up nested context | context = p.tableMerge(context, subcontext) -- pull up nested context | ||
local values = {} | local values = {} | ||
if | if (v[1] == nil) then --key value array = object/dict | ||
local subproperties_res = p.getSemanticProperties({jsonschema=schema, jsondata=v, properties=p.copy(subobject_properties), store=true, root=false, debug=debug, context=context, subschema=schema_properties[k], parent_schema_property=property_data[k]}) | local subproperties_res = p.getSemanticProperties({jsonschema=schema, jsondata=v, properties=p.copy(subobject_properties), store=true, root=false, debug=debug, context=context, subschema=schema_properties[k], parent_schema_property=property_data[k]}) | ||
local id = subproperties_res.id --subobject_id | local id = subproperties_res.id --subobject_id | ||
Line 854: | Line 790: | ||
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] | |||
else properties['Display title of'] = p.defaultArg(subschema['title'], "") 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,099: | Line 1,032: | ||
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 | end | ||
edits