[Twisted-web] On Flatteners and Adapters

Pedro Sanchez psanchez at nortel.com
Sat Aug 20 07:10:44 MDT 2005

The original version of my program registers Adapters and fails because 
of flatteners. Following your suggestion, here is a version registering 
flatteners instead. And it fails because of Adapters :|

twisted.python.components.CannotAdapt: <Menu object at 0xb77581ec> to 
<MetaInterface nevow.inevow.IRenderer>

I'd appreciate any suggestions.



Sanchez, Pedro [CAR:1A10:EXCH] wrote:
> Phil Frost wrote:
>> On Fri, Aug 19, 2005 at 07:14:34PM -0400, Pedro Sanchez wrote:
>>> Hello,
>>> I'm trying to implement a menu with the attached code, but it fails with
>>> the following error:
>>> exceptions.NotImplementedError: There is no flattener function
>>> registered for object <Menu object at 0xb76dd42c> of type <class
>>> 'Menu'>.
>>> ...
>>> I don't understand why it complains about flatteners not defined. Isn't
>>> that covered by the registered adapters? I'd appreciate any help.
>>> Thank you,
>>> -- 
>>> Pedro
>> It used to work like that. A while ago, a change was made to how
>> flatteners are registered; nevow.flat.registerFlattener is the new way
>> to do it:
>> from nevow import flat
>> class Bleh(object):
>>     pass
>> def flattenBleh(original, context):
>>     return 'a bleh thing'
>> flat.registerFlattener(flattenBleh, Bleh)
> Thanks,
> I will check this. However, the recipe in the Python cookbook website 
> works well and it doesn't use the interface you mention. So my code 
> should in theory work, provided I fix whatever is broken :)
-------------- next part --------------
from twisted.application import internet, service
from nevow import appserver, inevow, rend, compy, loaders, url
from nevow import tags as T
from nevow import flat

class Menu(object):
    def __init__(self, title, *items):
        self.title = title
        self.items = items

class MenuItem(object):
    def __init__(self, title, target):
        self.title = title
        self.target = target

def MenuView(original, context):
    return T.div[
        T.ul[[T.li[x] for x in original.items]]

def MenuItemView(original, context):
    return T.a(href=original.title)[original.target]

flat.registerFlattener(MenuView, Menu)
flat.registerFlattener(MenuItemView, MenuItem)

# some data
menu = Menu('Main Menu',
            Menu('Item 1',
                 MenuItem('1-1', url.root.child('oneone')),
                 MenuItem('1-2', url.root.child('onetwo')),
            MenuItem('2', url.root.child('two')),
            MenuItem('3', url.root.child('three'))

class Page(rend.Page):
    def render_menu(self, context, data):
        return inevow.IRenderer(data)

    def data_menu(self, context, data):
        return menu

    docFactory = loaders.stan(
            T.invisible(render=T.directive('menu'), data=T.directive('menu'))

site = appserver.NevowSite(Page())
application = service.Application("menu")
httpd = internet.TCPServer(8000, site).setServiceParent(application)

More information about the Twisted-web mailing list