Module:BuildVersionTree: Difference between revisions
From Seven Sages of Rome
(Created page with "-- Module:VersionTree local p = {} -- Helper function to build a tree structure from flat data local function buildTree(versions, parentField) local tree = {} local nodes = {} -- First pass: Create all nodes for _, version in ipairs(versions) do nodes[version.title] = { title = version.title, children = {}, processed = false } end -- Second pass: Build relationships for _, version...") |
No edit summary |
||
Line 1: | Line 1: | ||
-- Module:VersionTree | -- Module:VersionTree | ||
local p = {} | local p = {} | ||
-- Helper function to safely access table values | |||
local function safeGet(tbl, key) | |||
if tbl and type(tbl) == "table" then | |||
return tbl[key] | |||
end | |||
return nil | |||
end | |||
-- Helper function to build a tree structure from flat data | -- Helper function to build a tree structure from flat data | ||
Line 9: | Line 17: | ||
-- First pass: Create all nodes | -- First pass: Create all nodes | ||
for _, version in ipairs(versions) do | for _, version in ipairs(versions) do | ||
nodes[version. | if version and version.fulltext then | ||
nodes[version.fulltext] = { | |||
title = version.fulltext, | |||
children = {}, | |||
processed = false | |||
} | |||
end | |||
end | end | ||
-- Second pass: Build relationships | -- Second pass: Build relationships | ||
for _, version in ipairs(versions) do | for _, version in ipairs(versions) do | ||
local parent = version[parentField] | if version and version.fulltext then | ||
local parent = nil | |||
if version[parentField] and type(version[parentField]) == "table" then | |||
parent = version[parentField][1] | |||
end | |||
if parent and nodes[parent] then | |||
table.insert(nodes[parent].children, nodes[version.fulltext]) | |||
else | |||
-- If no parent or parent doesn't exist, it's a root node | |||
table.insert(tree, nodes[version.fulltext]) | |||
end | |||
end | end | ||
end | end | ||
Line 172: | Line 188: | ||
-- Main function to process the versions and generate tree view | -- Main function to process the versions and generate tree view | ||
function p.getTree(frame) | function p.getTree(frame) | ||
-- Debug output | |||
local debug = {} | |||
local versions = mw.smw.ask({ | local versions = mw.smw.ask({ | ||
"[[Category:Version||Secondary Version]]", | "[[Category:Version||Secondary Version]]", | ||
Line 177: | Line 196: | ||
}) | }) | ||
if not versions then | if not versions or type(versions) ~= "table" or #versions == 0 then | ||
return "No versions found." | return "No versions found in the Category:Version or Secondary Version." | ||
end | end | ||
Line 184: | Line 203: | ||
local processedVersions = {} | local processedVersions = {} | ||
for _, version in ipairs(versions) do | for _, version in ipairs(versions) do | ||
table.insert(processedVersions, { | if version and version.fulltext then | ||
table.insert(processedVersions, { | |||
fulltext = version.fulltext, | |||
["Has Parent Version"] = version["Has Parent Version"] | |||
}) | |||
-- Add debug information | |||
table.insert(debug, "Processing: " .. version.fulltext) | |||
if version["Has Parent Version"] then | |||
table.insert(debug, " Parent: " .. tostring(version["Has Parent Version"][1])) | |||
end | |||
end | |||
end | |||
if #processedVersions == 0 then | |||
return "No valid versions found to process." | |||
end | end | ||
Line 210: | Line 240: | ||
table.insert(result, '</div>') | table.insert(result, '</div>') | ||
-- Add debug information if needed | |||
-- table.insert(result, '<pre>' .. table.concat(debug, '\n') .. '</pre>') | |||
return table.concat(result, '\n') | return table.concat(result, '\n') |
Revision as of 18:51, 23 October 2024
Documentation for this module may be created at Module:BuildVersionTree/doc
-- Module:VersionTree
local p = {}
-- Helper function to safely access table values
local function safeGet(tbl, key)
if tbl and type(tbl) == "table" then
return tbl[key]
end
return nil
end
-- Helper function to build a tree structure from flat data
local function buildTree(versions, parentField)
local tree = {}
local nodes = {}
-- First pass: Create all nodes
for _, version in ipairs(versions) do
if version and version.fulltext then
nodes[version.fulltext] = {
title = version.fulltext,
children = {},
processed = false
}
end
end
-- Second pass: Build relationships
for _, version in ipairs(versions) do
if version and version.fulltext then
local parent = nil
if version[parentField] and type(version[parentField]) == "table" then
parent = version[parentField][1]
end
if parent and nodes[parent] then
table.insert(nodes[parent].children, nodes[version.fulltext])
else
-- If no parent or parent doesn't exist, it's a root node
table.insert(tree, nodes[version.fulltext])
end
end
end
return tree
end
-- Helper function to generate unique IDs for nodes
local function generateId(text)
return 'node-' .. mw.uri.encode(text):gsub('%%', '-')
end
-- Helper function to render a tree node and its children
local function renderNode(node, level)
local result = {}
-- Generate unique ID for this node
local nodeId = generateId(node.title)
-- Create node container
table.insert(result, string.format('<div class="tree-node level-%d" id="%s">', level, nodeId))
-- Add node content
table.insert(result, string.format('<div class="node-content"><div class="node-box">[[%s]]</div></div>', node.title))
if #node.children > 0 then
-- Add container for children
table.insert(result, '<div class="node-children">')
-- Sort children by title
table.sort(node.children, function(a, b)
return a.title < b.title
end)
-- Render children
for _, child in ipairs(node.children) do
table.insert(result, renderNode(child, level + 1))
end
table.insert(result, '</div>')
end
table.insert(result, '</div>')
return table.concat(result, '\n')
end
-- Function to generate CSS styles
local function getStyles()
return [[
<style>
.version-tree {
text-align: center;
padding: 20px;
font-family: sans-serif;
}
.tree-node {
display: inline-block;
vertical-align: top;
text-align: center;
padding: 0 10px;
position: relative;
}
.node-content {
position: relative;
padding: 10px 0;
}
.node-box {
display: inline-block;
border: 1px solid #ccc;
border-radius: 5px;
padding: 5px 15px;
background: #f8f9fa;
position: relative;
z-index: 1;
}
.node-children {
position: relative;
margin-top: 20px;
}
/* Lines connecting nodes */
.node-children:before {
content: '';
position: absolute;
top: -20px;
left: 50%;
border-left: 1px solid #ccc;
height: 20px;
}
.tree-node .tree-node:before {
content: '';
position: absolute;
top: 0;
left: 50%;
border-left: 1px solid #ccc;
height: 10px;
}
.node-children .tree-node:first-child:after,
.node-children .tree-node:last-child:after {
content: '';
position: absolute;
top: 0;
width: 50%;
height: 10px;
border-top: 1px solid #ccc;
}
.node-children .tree-node:first-child:after {
right: 50%;
}
.node-children .tree-node:last-child:after {
left: 50%;
}
.node-children .tree-node:only-child:after {
display: none;
}
/* Horizontal line connecting siblings */
.node-children {
position: relative;
}
.node-children:after {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
border-top: 1px solid #ccc;
}
.node-children .tree-node:only-child:before {
height: 10px;
}
</style>
]]
end
-- Main function to process the versions and generate tree view
function p.getTree(frame)
-- Debug output
local debug = {}
local versions = mw.smw.ask({
"[[Category:Version||Secondary Version]]",
"?Has Parent Version"
})
if not versions or type(versions) ~= "table" or #versions == 0 then
return "No versions found in the Category:Version or Secondary Version."
end
-- Transform SMW results into a format suitable for tree building
local processedVersions = {}
for _, version in ipairs(versions) do
if version and version.fulltext then
table.insert(processedVersions, {
fulltext = version.fulltext,
["Has Parent Version"] = version["Has Parent Version"]
})
-- Add debug information
table.insert(debug, "Processing: " .. version.fulltext)
if version["Has Parent Version"] then
table.insert(debug, " Parent: " .. tostring(version["Has Parent Version"][1]))
end
end
end
if #processedVersions == 0 then
return "No valid versions found to process."
end
-- Build tree
local tree = buildTree(processedVersions, "Has Parent Version")
-- Sort root nodes
table.sort(tree, function(a, b)
return a.title < b.title
end)
-- Generate output
local result = {
getStyles(),
'<div class="version-tree">'
}
-- Render each root node
for _, node in ipairs(tree) do
table.insert(result, renderNode(node, 0))
end
table.insert(result, '</div>')
-- Add debug information if needed
-- table.insert(result, '<pre>' .. table.concat(debug, '\n') .. '</pre>')
return table.concat(result, '\n')
end
return p