[Twisted-web] Page object design: wrapping a dictionary containing data

Matt Goodall matt at pollenation.net
Sun Jan 23 07:09:31 MST 2005


On Sun, 2005-01-23 at 20:14 +1000, Andy Gayton wrote:
> Mary Gardiner wrote:
> 
>  > What's a good way for the Page object to wrap that dictionary that
>  > doesn't involve doing this:
>  >
>  >     def data_name(self, ctx, data):
>  >         return self.d['project_name']
>  >
>  > ...
>  >
>  > I vaguely recall that the equivalent of this used to be possible in
>  > Woven:
>  >
>  >     def data_project(self, ctx, data):
>  >         return self.d
>  >
>  > and then that the data items were accessible by (say)
>  > stan.directive("project/project_name"). This doesn't look like its
>  > supported in Nevow. Is this correct? What alternative designs are there
>  > for something like this?
> 
> heya Mary,
> 
> there's a lot of Nevow magic I don't know, but in case something doesn't 
> exist, something like the following should work, albeit, pretty crude:
> 
> python -c '
> class C:
>      def __getattr__( self, attr ):
>          if attr.startswith( "data_" ):
>              return lambda ctx, data, s=self, a=attr : s.d["project_%s" 
> % a[len("data_"):]]
>          raise AttributeError
> 
> c = C()
> 
> c.d  = { "project_name" : "roar" }
> ctx  = "ned"
> data = "fred"
> 
> print c.data_name( ctx, data )

I'm not entirely sure where the above would be used but it *looks*
suspiciously like some sort of pseudo-adaption for type C. If that's the
case then you can register an inevow.IContainer adapter and avoid
polluting your application classes with stuff that only Nevow needs ...

        class Person:
            def __init__(self, name, address):
                self.name = name
                self.address = address
        
        class PersonContainer(Adapter):
            __implements__ = inevow.IContainer,
            def child(self, name):
                return getattr(self.original, name)
        
        registerAdapter(PersonContainer, Person, inevow.IContainer)

Yes, I agree it's a bit long-winded to have to do that every time ;-).
So, there is now a ready made adapter for this in svn trunk -
accessors.ObjectContainer - that does the above. Just register it for
your type and it will magically work ...

        class Person:
            def __init__(self, name, address):
                self.name = name
                self.address = address
        
        registerAdapter(accessors.ObjectContainer, Person,
                        inevow.IContainer)

There's an example of this in svn trunk too. See, objcontainer.py.

Hope this helps.

Cheers, Matt




More information about the Twisted-web mailing list