Module:GetRels
From Bodhicitta
Documentation for this module may be created at Module:GetRels/doc
local p = {}
function p.main(frame)
-- pass in parent arguments from template
local pArgs = frame:getParent().args
-- get local pagename
local pagename = mw.title.getCurrentTitle().subpageText
-- query for vertical relationships names
local relsDirection = {}
local verticRelsQueryData = mw.ext.externalData.getExternalData{
url = 'https://research.tsadra.org/index.php?title=Special%3AAsk&q=' .. mw.uri.encode( '[[-Has subobject::Property:Relationship]][[RelPropDir::vertical]]' ) .. '&po=RelPropName&p%5Blimit%5D=108&p%5Bformat%5D=csv',
data = { RelPropName = 'RelPropName'},
format = 'CSV with header'
}
for _, data in pairs( verticRelsQueryData ) do
relsDirection[data.RelPropName] = 'vertical'
end
-- query for horizontal relationships names
local horizRelsQueryData = mw.ext.externalData.getExternalData{
url = 'https://research.tsadra.org/index.php?title=Special%3AAsk&q=' .. mw.uri.encode( '[[-Has subobject::Property:Relationship]][[RelPropDir::horizontal]]' ) .. '&po=RelPropName&p%5Blimit%5D=108&p%5Bformat%5D=csv',
data = { RelPropName = 'RelPropName'},
format = 'CSV with header'
}
local horizRels = {}
for _, data in pairs( horizRelsQueryData ) do
relsDirection[data.RelPropName] = 'horizontal'
end
-- build query string for main relationship subobject query and ASK query
local queryResult = mw.ext.externalData.getExternalData{
url = 'https://research.tsadra.org/index.php?title=Special%3AAsk&q=' .. mw.uri.encode( '[[-Has subobject::' .. mw.title.getCurrentTitle().subpageText .. ']][[RelatedTo::+]][[RelationshipType::!ResourceToPerson]]OR[[RelatedTo::' .. mw.title.getCurrentTitle().subpageText .. ']][[RelationshipType::!ResourceToPerson]]' ) .. '&po=RelatedTo%0ARelationship&p%5Blimit%5D=10000&p%5Bmainlabel%5D=Page&p%5Bformat%5D=csv',
data = {
Page = 'Page',
RelatedTo = 'RelatedTo',
Relationship = 'Relationship'
},
format = 'CSV with header'
}
-- define var for our main output
local myResult = ''
-- check if query is empty first, if so, no need to go on
if queryResult == nil then return "No results!" end
-- build our result string with intro element tag
myResult = myResult .. '<h1>Relationships</h1><table id="RelationshipsContent" class="smwtable-clean th-top-right th-nowrap border">'
-- check if more than 15 query results, if so, add filters to top of table
if #queryResult > 15 then
local filterRels = frame:callParserFunction{
name = '#widget', args = {
'FilterRelationships',
id = 'Relationships',
placeholder = 'Filter by relationships...'
}
}
local filterPages = frame:callParserFunction{
name = '#widget', args = {
'FilterRelationships',
id = 'Pages',
placeholder = 'Filter by pages found...'
}
}
myResult = myResult .. '<tr><td>' .. filterRels .. '</td><td></td><td>' .. filterPages .. '</td></tr>'
end
-- define table vars for storing different relationships
local InRels = {}
local OutRels = {}
local InferredRels = {}
-- iterate through our query results
for num, data in ipairs( queryResult ) do
-- define a few pagename vars, page where subobject was found, encode both local and result pagenames so as to compare
local page = frame:preprocess( '{{PAGENAME:' .. data.Page .. '}}' )
local pageEnc = mw.uri.anchorEncode( page )
local pagenameEnc = mw.uri.anchorEncode( pagename )
-- checking if both local and result pagenames are the same, if so, we're talking about a relationship that is set locally, going out from this page
if pageEnc == pagenameEnc then
-- defining variable that will hold the list of result pages for the given relationhsip
local relatedToPages = ''
-- checking if only 1 result, if more, iterate and build the list
if data.RelatedTo == nil then
relatedToPages = '<li class="filterable"><span style="color:red;">No item specified!</span></li>'
else
if type(data.RelatedTo) == "table" then
for num, value in ipairs( data.RelatedTo ) do
relatedToPages = relatedToPages .. '<li class="filterable">[[' .. value .. ']]</li>'
end
else
relatedToPages = '<li class="filterable">[[' .. data.RelatedTo .. ']]</li>'
end
end
-- let's populate the outgoing relationships table
if OutRels[data.Relationship] then
OutRels[data.Relationship] = OutRels[data.Relationship] .. relatedToPages
else
-- quick check to see if the relationship was set properly, if not, well... that's no good now is it!
if data.Relationship == nil then
OutRels['<span style="color:red;">Relationship not set!</span>'] = relatedToPages
else
OutRels[data.Relationship] = relatedToPages
end
end
else
-- for incoming relationship, let's do a quick check to see if it's a media page, and it's part of a bigger series, if so, let's only take the first track, otherwise there can be too many results
local mediaCheckQuery = mw.ext.externalData.getExternalData{
url = 'https://research.tsadra.org/index.php?title=Special%3AAsk&q=' .. mw.uri.encode( '[[' .. page .. ']][[MediaSeries::+]][[Volumenumber::>>1]]' ) .. '&p%5Bmainlabel%5D=wikipage&p%5Blimit%5D=108&p%5Bformat%5D=csv&p%5Bdefault%5D=',
data = { wikipage = 'wikipage'},
format = 'CSV with header'
}
if not mediaCheckQuery == nil or tostring(#mediaCheckQuery) == '0' then
-- if we're good to go, let's populate the incoming relationships table
-- let's first check if the relationship was actually set properly
local rel = ''
if data.Relationship then
rel = data.Relationship
else
-- if not let's make it obvious
rel = '<span style="color: red; font-weight: bold;">Relationship not properly set!</span>'
end
-- now let's get the actual display title of the page
local val = mw.ext.displaytitle.get(page)
-- and feed that title into the list of incoming relationships to be displayed on the page, for the proper relationship
if InRels[rel] then
InRels[rel] = InRels[rel] .. '<li class="filterable">[[' .. page .. '|' .. val .. ']]</li>'
else
InRels[rel] = '<li class="filterable">[[' .. page .. '|' .. val .. ']]</li>'
end
-- Now find any further INFERRED relationships, let's check if the relationship is horizontal
if relsDirection[rel] == 'horizontal' then
-- if it's horizontal, let's query more to figure out the inferred relationships of this property, via the page found. For example if this page (A) is another edition of the page found in the query above (B), let's query for any other page that might be other editions of page B, like C, D, E. Those would also be other editions of A.
-- another ED query to find our results
local inferredQR = mw.ext.externalData.getExternalData{
url = 'https://research.tsadra.org/index.php?title=Special%3AAsk&q=' .. mw.uri.encode( '[[-Has subobject::!' .. pagename .. ']][[RelatedTo::' .. page .. ']][[Relationship::' .. rel .. ']]OR[[-Has subobject::' .. page .. ']][[Relationship::' .. rel .. ']]' ) .. '&po=RelatedTo&p%5Bmainlabel%5D=InferredPage&p%5Blimit%5D=10000&p%5Blink%5D=none&p%5Bformat%5D=csv',
data = { InferredPage = 'InferredPage', RelatedTo = 'RelatedTo' },
format = 'CSV with header'
}
myResult = myResult .. #inferredQR
-- check if empty first
if inferredQR then
-- if not, let's parse through our results
for _, infData in ipairs( inferredQR ) do
-- from the results, let's see if our page B is the same as what's in the RelatedTo field of our results, if so, it means we're talking about a page C here
if infData.RelatedTo == page then
-- let's strip the subobject hash from our page C pagename, we want the pagename that HOLDS the subobject, not the wiki name of the subobject itself.
local infPage = frame:preprocess( '{{PAGENAME:' .. infData.InferredPage .. '}}' )
-- let's get the displaytitle value for that page. If it's a classical work, it could be in the format RKTS### which isn't helpful. We want the actual title of the work.
local infVal = mw.ext.displaytitle.get(infPage)
-- let's feed those titles into the list of incoming relationships to be displayed on the page, for the proper horizontal inferred relationship
if InRels[rel] then
InRels[rel] = InRels[rel] .. '<li class="filterable">[[' .. infPage .. '|' .. infVal .. ']]</li>'
else
InRels[rel] = '<li class="filterable">[[' .. infPage .. '|' .. infVal .. ']]</li>'
end
-- if our page B is not what's in RelatedTo, then we're talking about other relationships defined on page B that we want to list, cause they're horizontal so apply to our page A.
-- let's check if RelatedTo is a table of value, it should since it's already holding the value for page A (that's how we found it in the first place, remember?), we're looking for those other values.
elseif type(infData.RelatedTo) == "table" then
-- let's parse through those values
for _, value in ipairs( infData.RelatedTo ) do
-- let's check if one of these values is our page A, cause we obviously don't need to list that.
if value ~= pagename then
-- find the displaytitle for our other values
local infVal = mw.ext.displaytitle.get(value)
-- and feed those titles into the list of incoming relationships to be displayed on the page, for the proper horizontal inferred relationship
if InRels[rel] then
InRels[rel] = InRels[rel] .. '<li class="filterable">[[' .. value .. ']]</li>'
else
InRels[rel] = '<li class="filterable">[[' .. value .. ']]</li>'
end
else
end
end
end
end
end
end
end
end
end
-- now let's use the outgoing relationship table to build our table rows
for rel, vals in pairs( OutRels ) do
myResult = myResult .. '<tr><th>' .. rel .. '</th><td style="color: green;"><i class="fa-duotone fa-arrow-right"></i></td><td><ol style="margin: 0 1.3em;" class="sort-ascending">' .. vals .. '</ol></td></tr>'
end
-- and the incoming relationship table to build our table rows
for rel, vals in pairs( InRels ) do
myResult = myResult .. '<tr><th>' .. rel .. ' <div class="font-weight-normal font-italic">this work</div></th><td style="color: blue;"><i class="fa-duotone fa-arrow-left"></i></td><td><ol style="margin: 0 1.3em;" class="sort-ascending">' .. vals .. '</ol></td></tr>'
end
-- close our table tag and we're good to go!
myResult = myResult .. '</table>'
return myResult
end
return p