+ local path = {...}
+ local url = { http.getenv("SCRIPT_NAME") or "" }
+
+ local k, v
+ for k, v in pairs(context.urltoken) do
+ url[#url+1] = "/;"
+ url[#url+1] = http.urlencode(k)
+ url[#url+1] = "="
+ url[#url+1] = http.urlencode(v)
+ end
+
+ local p
+ for _, p in ipairs(path) do
+ if p:match("^[a-zA-Z0-9_%-%.%%/,;]+$") then
+ url[#url+1] = "/"
+ url[#url+1] = p
+ end
+ end
+
+ return table.concat(url, "")
+end
+
+--- Check whether a dispatch node shall be visible
+-- @param node Dispatch node
+-- @return Boolean indicating whether the node should be visible
+function node_visible(node)
+ if node then
+ return not (
+ (not node.title or #node.title == 0) or
+ (not node.target or node.hidden == true) or
+ (type(node.target) == "table" and node.target.type == "firstchild" and
+ (type(node.nodes) ~= "table" or not next(node.nodes)))
+ )
+ end
+ return false
+end
+
+--- Return a sorted table of visible childs within a given node
+-- @param node Dispatch node
+-- @return Ordered table of child node names
+function node_childs(node)
+ local rv = { }
+ if node then
+ local k, v
+ for k, v in util.spairs(node.nodes,
+ function(a, b)
+ return (node.nodes[a].order or 100)
+ < (node.nodes[b].order or 100)
+ end)
+ do
+ if node_visible(v) then
+ rv[#rv+1] = k
+ end
+ end
+ end
+ return rv