import random
from twisted.application import service
from twisted.application import internet
from nevow import appserver
from nevow import renderer
from nevow import tags
def flatten_menu(data):
html_menu = "
"
items = data.items()
items.sort()
for k, v in items:
html_menu += "- %s
" % k
html_menu += ""
v.sort()
for i in v:
if isinstance(i, dict):
html_menu += flatten_menu(i)
else:
html_menu += "- %s
" % i
html_menu += "
"
html_menu += "
"
return html_menu
class Menus(renderer.Renderer):
document = tags.html[
tags.head[tags.title["Hello"]],
tags.body[
tags.div(style="border: 1px dotted black; margin: 1em")[
tags.ul(renderer=tags.directive("menu"))
],
tags.div(style="border: 1px dotted black; margin: 1em")[
tags.ul(renderer=tags.directive("stan_menu"))
]
]
]
def render_menu(self, context, data):
return tags.xml(flatten_menu(data))
def render_stan_menu(self, context, data):
"""Render a dictionary of string keys and list of string/dict values."""
menu = context.tag
items = data.items()
items.sort()
for k, v in items:
# Add a list item with our key as the label
menu.children.append(tags.li[k])
# Add an ul tag to this menu for the submenu
submenu = tags.ul()
menu.children.append(submenu)
# For every element of the value list
v.sort()
for i in v:
# if it's a dict, cause render_stan_menu to be called on it, and the output placed in the submenu tag
if isinstance(i, dict):
submenu.children.append(tags.ul(data=i, renderer=self.render_stan_menu))
# if it's a string, just add a list item with the string to the menu
else:
submenu.children.append(tags.li[ i ])
return menu
menu_items = {
"A": ["a", "b", "c"],
"B": ["d", "e", "f"],
"C": ["g", "h", {"i":
["x", "y", "z"]
}]
}
application = service.Application("nestedmenus")
internet.TCPServer(
8080,
appserver.NevowSite(
Menus(
menu_items
)
)
).setServiceParent(application)