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 = "" 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)