Nevow Tutorial

Using child_name() Methods and child_name Attributes

######################################################################
# Run using 'twistd -noy file.tac', then point your browser to
# http://localhost:8080
# A very simple Nevow site.
######################################################################

from twisted.application import service, internet

from nevow               import appserver
from nevow               import rend
from nevow               import loaders
from nevow               import tags as T

class SubPage ( rend.Page ):

    def __init__ ( self, *args, **kwargs ):
        rend.Page.__init__ ( self, *args, **kwargs )
        self.viewed = 0;
        self.docFactory = self.makeDocFactory()

    def render_content ( self, ctx, data ):
        self.viewed += 1
        return "I have been viewed %d times." % ( self.viewed, )

    def makeDocFactory ( self ):
        return loaders.stan (
            T.html [ T.head ( title = 'Sub Page' ),
                     T.body [ T.h1 [ "This is a Sub Page" ],
                              T.p ( render = T.directive ( "content" ) )
                     ]
                   ]
            )


class MainPage ( rend.Page ):

    def __init__ ( self, *args, **kwargs ):
        rend.Page.__init__ ( self, *args, **kwargs )
        self.foopage = SubPage()
        self.barpage = SubPage()


    docFactory = loaders.stan (
        T.html [ T.head ( title = 'Main Page' ),
                 T.body [ T.h1 [ "This is the Main Page" ],
                          T.p [ "Try going to the pages ",
                                T.a ( href = 'foo' ) [ "foo" ],
                                " or ",
                                T.a ( href = 'bar' ) [ "bar" ],
                                " or ",
                                T.a ( href = 'baz' ) [ "baz" ],
                                ],
                          T.p [ "Don't try going ",
                                T.a ( href = 'zzz' ) [ "here" ],
                                " as it doesn't exist."
                                ]
                          ]
                 ]
        )


    def child_foo ( self, ctx ):
        return self.foopage

    def child_bar ( self, ctx ):
        return self.barpage

    child_baz = SubPage()

######################################################################
# Nevow Boilerplate
######################################################################

application = service.Application ( "nevowdemo" )
port        = 8080
res         = MainPage()
site        = appserver.NevowSite ( res )
webService  = internet.TCPServer ( port, site )
webService.setServiceParent ( application )

This example does the page lookup differently from the previous examples, and it has also slipped in a few new features for the eagle-eyed:

  • Instead of a children dictionary the MainPage class now has two methods, child_foo() and child_bar() that return the pages;
  • The pages are stored on self, so the same object is returned from the method each time a page is accessed. Note that this was also the case in the children-dict example, but not in some previous examples, where they were instantiated on demand.
  • Pages can also be stored on attributes as well as returned by methods; child_baz is such an attribute.
  • SubPage creates and assigns a docFactory in the constructor rather than a class attribute, just to show that it's possible;
  • Importantly, SubPage now stores state: each time it is accessed, it reports the number of time the page has been viewed;

Don't worry too much about the last point; that will be covered soon. It's just a little taster to show off some of Nevow's more advanced features.

Proceed on to DivmodNevow/TutorialSix.

jethro@divmod.org