[Twisted-web] fragments with child lookup

Valentino Volonghi aka Dialtone dialtone at divmod.com
Sat Sep 23 09:22:06 CDT 2006

>I've learned about nevow macros. I don't quite understand what the big 
>difference to a renderer is, but that's another story...

One is processed once and only once at pre-compile time, the other is not.

>I'm still trying to get my 'component' based thinking migrated to nevow. As 
>an exercise, I thought I'd try to use the nevow example pastebin as a 
>component. What I want to achieve is having the pastebin available under 
>http://localhost:8080/pastebin/, wrapped within my own template.
>http://localhost:8080/  should simply show a welcome page, within the same 

You can't do that because pastebin is not designed to be used in that way. Otherwise simply return the root page of the pastebin from the child_pastebin method of the root page of your site.

>Index: pastebin.tac
>--- pastebin.tac        (revision 9132)
>+++ pastebin.tac        (working copy)
>@@ -5,6 +5,7 @@
>  from nevow import appserver
>  from nevow import vhost
>+from nevow import inevow, rend, stan, loaders, tags as T
>  from pastebin import interfaces
>  from pastebin.service import FSPasteBinService
>@@ -16,7 +17,31 @@
>  pastebin = FSPasteBinService('data')
>  pastebin.setServiceParent(application)
>-appResource = pages.RootPage(pastebin)
>+class SuperiorRootPage(rend.Page):
>+    addSlash = True
>+    docFactory = loaders.stan(
>+        T.html[
>+            T.head(),
>+            T.body[
>+                T.h1['hello world'],
>+                T.invisible(macro=T.directive('content')),
>+            ]])
>+    def locateChild(self, ctx, segments):
>+        self.remaining_segments = segments[1:]
>+        return self, ()

This stuff above is just wrong.

>+    child_pastebin = pages.RootPage(pastebin)
>+    def macro_content(self, ctx):
>+        print "remaining_segments: %s" % str(self.remaining_segments)
>+        if len(self.remaining_segments) == 0:
>+            return "welcome!"
>+        else:
>+            # what to return here???
>+            return "duh!"
>+appResource = SuperiorRootPage(pastebin)
>  appResource.putChild('robots.txt', static.File('static/robots.txt'))
>  vResource = vhost.VHostMonsterResource()
>  appResource.putChild('vhost', vResource)

As I told you the first time you should use a dictionary that contains fragments, in fact that's exactly what you should do.

What you are trying to do is far less dynamic than what you tried to explain.

Just pass the docFactory argument to the Page class when you create it and let the Fragments render themselves with the appropriate template (when the are needed, and they are not strictly here).

if you only want to change the outer parts of a page then use the macro system (it is _static_ and request agnostic, it's compiled at the first request but has no connection with it (and it's wrong to act in that way).

Use a single macro.html template in your application and write everything else in order to fill the macro slots, when you need to change the macro change it (the macro template is the docFactory of the base Page class, when the rest inherits it will fill the content macro (or sidebar or whatever macro) with its own template that statically depends on the page you are writing in that moment.

More information about the Twisted-web mailing list