I'm trying to extend StaticFileHandler
in such a way that I can process file requests but call self.render(filename, **kwargs)
on the file to actually serve it to the client. (Yes, I realize that at that point it's no longer a static file per se).
Here's the code I'm trying to run:
class MustacheFileHandler(tornado.web.StaticFileHandler):
def get(self, filename):
self.render(_STATIC_ROOT_ + '/' + path.split('/')[len(path.split('/'))-2], userLoginStatus='you are logged out!')
# ...
class Application(tornado.web.Application):
def __init__(self, **overrides):
handlers = [(r'/(.*)', MustacheFileHandler, {'path' : _STATIC_ROOT_})]
# ...
... Where _STATIC_ROOT_
is a variable included in my server's config file loaded on startup.
The issue I've got is, whenever I try to do a GET
on a file I know exists on the server, I get the following error:
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/tornado/web.py", line 1332, in _execute
result = method(*self.path_args, **self.path_kwargs)
File "myfile.py", line 173, in get
self.render(_STATIC_ROOT_ + '/' + path.split('/')[len(path.split('/'))-2], userLoginStatus='you are logged out!')
File "/usr/local/lib/python2.7/dist-packages/tornado/web.py", line 747, in render
self.finish(html)
File "/usr/local/lib/python2.7/dist-packages/tornado/web.py", line 877, in finish
self.set_etag_header()
File "/usr/local/lib/python2.7/dist-packages/tornado/web.py", line 1257, in set_etag_header
etag = self.compute_etag()
File "/usr/local/lib/python2.7/dist-packages/tornado/web.py", line 2185, in compute_etag
version_hash = self._get_cached_version(self.absolute_path)
AttributeError: 'MustacheFileHandler' object has no attribute 'absolute_path'
I'm not sure what's causing this error or how I can handle it.
Why are you using StaticFileHandler if the response is not static? This is likely to break assumptions built into the class.
StaticFileHandler is designed to be subclassed in limited ways as described in its documentation. In particular, subclasses should not override
get()
, and attempting to do so results in the error you're seeing.If you want to use the Tornado template engine as a kind of preprocessor of the files on disk, you could try to do this by overriding both
get_content
andget_content_size
, and making them callself.render_string()
(also consider that if your templates are not individually self-contained you'll need to changeget_content_version
to take all dependencies into account). However, this requires messy caching to avoid rendering the template multiple times. It's probably better to either A) Render the templates on the fly with an ordinary RequestHandler. or B) Write a little script to render all your templates, write them to disk, and serve the results as actual static files.