Can you explain *why* you have the following code (copied from your original post):
from twisted.application import service from twisted.application import internet class ADir(rend.Page): def locateChild(self, request, segments): path = '/'.join(segments) return static.File(path), () application = service.Application('ADirlist') webservice = internet.TCPServer( 8080, appserver.NevowSite(ADir()) ) webservice.setServiceParent(application)
What is the use case? Why not let static.File handle everything?
Well... it is certainly possible that I am going about this all wrong.
I was trying to figure out how to serve images from the nevow server to go along with my web pages. This was the first way I figured to do that.
If there is a better way, I am certainly willing to use it.
Is this code flawed in some way? When I try to run it without that patch, I get an error like this trying to load the root url:
2004/04/04 20:52 EDT [HTTPChannel,0,127.0.0.1] Traceback (most recent call last): File "/usr/local/lib/python2.3/site-packages/twisted/protocols/http.py", line 554, in requestReceived self.process() File "/usr/local/lib/python2.3/site-packages/nevow/appserver.py", line 130, in process return self.site.getResourceFor( File "/usr/local/lib/python2.3/site-packages/twisted/internet/defer.py", line 189, in addCallback callbackKeywords=kw) File "/usr/local/lib/python2.3/site-packages/twisted/internet/defer.py", line 180, in addCallbacks self._runCallbacks() --- <exception caught here> --- File "/usr/local/lib/python2.3/site-packages/twisted/internet/defer.py", line 313, in _runCallbacks self.result = callback(self.result, *args, **kw) File "/usr/local/lib/python2.3/site-packages/nevow/appserver.py", line 133, in <lambda> lambda resource: inevow.IResource(resource).renderHTTP(self) File "/usr/local/lib/python2.3/site-packages/nevow/static.py", line 290, in renderHTTP f = self.openForReading() File "/usr/local/lib/python2.3/site-packages/nevow/static.py", line 253, in openForReading return self.fp.open() File "/usr/local/lib/python2.3/site-packages/twisted/python/filepath.py", line 138, in open return open(self.path, mode+'b') exceptions.IOError: [Errno 21] Is a directory
2004/04/04 20:52 EDT [HTTPChannel,0,127.0.0.1] html is not a string: None
_________________________________________________________________ Tired of spam? Get advanced junk mail protection with MSN 8. http://join.msn.com/?page=features/junkmail
On Mon, 2004-04-05 at 02:03, Lee Harr wrote:
Can you explain *why* you have the following code (copied from your original post):
from twisted.application import service from twisted.application import internet class ADir(rend.Page): def locateChild(self, request, segments): path = '/'.join(segments) return static.File(path), () application = service.Application('ADirlist') webservice = internet.TCPServer( 8080, appserver.NevowSite(ADir()) ) webservice.setServiceParent(application)
What is the use case? Why not let static.File handle everything?
Well... it is certainly possible that I am going about this all wrong.
I was trying to figure out how to serve images from the nevow server to go along with my web pages. This was the first way I figured to do that.
Aha! All becomes clear.
If there is a better way, I am certainly willing to use it.
Yep, it's much simpler too :)
Although locateChild() is the "official" API for URL traversal, rend.Page adds some more convenient ways of specifying children. The one you probably want is so define a child_images attribute on your root page's class:
from twisted.application import internet, service from twisted.web import static
from nevow import appserver from nevow import rend from nevow import static
class RootPage(rend.Page):
# Mount the 'images' directory at the '/images' URl child_images = static.File('images')
docFactory = rend.htmlstr( ''' <html> <body> <img src="/images/TwistedLogoFull.png" /> <p>Blah, blah, blah</p> </body> </html> ''' )
application = service.Application('static') webServer = internet.TCPServer( 8000, appserver.NevowSite(RootPage())) webServer.setServiceParent(application)
*Note* ... static.File will publish individual files or an entire directory structure. It is up to you how you use it but for 'images', 'stylesheets', 'scripts' etc I tend to find it easier to publish a directory for each. You could even put the 'images', 'stylesheets' and 'scripts' directories in one 'static' directory and publish the whole thing with one child_static of something similar.
The other ways rend.Page helps you with this task are best demonstrated by examples/children.tac in Nevow's svn repository and (I think) the released source tar ball.
Hope this helps.
Cheers, Matt
At 2004-04-05 09:48 AM +0100, you wrote:
static.File will publish individual files or an entire directory structure. It is up to you how you use it but for 'images', 'stylesheets', 'scripts' etc I tend to find it easier to publish a directory for each.
This is what I do, as well. My app module is organized as: page [page renderers] css [CSS files] help [HTML and supporting files] image [image files used in rendered pages] javascript [javascript files] templates [templates for page renderers] misc [whatever wouldn't fit in the others] db [persistence] sql [sql for DB initial set, etc.] scripts [utilities for setup, etc.]
The app has a start/welcome page, with URL 'children' for CSS, help, image, and Javascript. The page class (an HTMLRenderer) defines:
cssDirectory = os.path.join(os.path.split(__file__)[0], "css") helpDirectory = os.path.join(os.path.split(__file__)[0], "help") imageDirectory = os.path.join(os.path.split(__file__)[0], "image") jsDirectory = os.path.join(os.path.split(__file__)[0], "javascript")
def child_css( self, request ): return static.File( self.cssDirectory, defaultType="text/css" )
def child_help( self, request ): return static.File( self.helpDirectory, defaultType="text/html" )
def child_image( self, request ): return static.File( self.imageDirectory, defaultType="image/gif" )
def child_js( self, request ): return static.File( self.jsDirectory, defaultType="text/javascript" )
I'm not sure how efficient this is, but it certainly works well. The ChildPrefixMixin already does the dispatching, and the result is very extensible and easy to understand.
- Sam
__________________________________________________________ Spinward Stars, LLC Samuel Reynolds Software Consulting and Development 303-805-1446 http://SpinwardStars.com/ sam@SpinwardStars.com
On Mon, 2004-04-05 at 17:11, Samuel Reynolds wrote:
At 2004-04-05 09:48 AM +0100, you wrote:
static.File will publish individual files or an entire directory structure. It is up to you how you use it but for 'images', 'stylesheets', 'scripts' etc I tend to find it easier to publish a directory for each.
This is what I do, as well. My app module is organized as: page [page renderers] css [CSS files] help [HTML and supporting files] image [image files used in rendered pages] javascript [javascript files] templates [templates for page renderers] misc [whatever wouldn't fit in the others] db [persistence] sql [sql for DB initial set, etc.] scripts [utilities for setup, etc.]
The app has a start/welcome page, with URL 'children' for CSS, help, image, and Javascript. The page class (an HTMLRenderer) defines:
cssDirectory = os.path.join(os.path.split(__file__)[0], "css") helpDirectory = os.path.join(os.path.split(__file__)[0], "help") imageDirectory = os.path.join(os.path.split(__file__)[0], "image") jsDirectory = os.path.join(os.path.split(__file__)[0], "javascript") def child_css( self, request ): return static.File( self.cssDirectory, defaultType="text/css" ) def child_help( self, request ): return static.File( self.helpDirectory, defaultType="text/html" ) def child_image( self, request ): return static.File( self.imageDirectory, defaultType="image/gif" ) def child_js( self, request ): return static.File( self.jsDirectory, defaultType="text/javascript" )
I'm not sure how efficient this is, but it certainly works well.
The advantage to using class attributes is that the child resources are only created once as there is often only one RootPage created for the application. Using child_ methods is useful when the resource needs to be initialised with args that are only known at request time.
Cheers, Matt