I have a Tornado application that I want to host under a non-root location with nginx. So I have an nginx configuration that looks like
server {
listen 80;
server_name mysite.com;
location /myapp/ {
proxy_pass http://localhost:8888/;
}
}
I want the app to live at mysite.com/myapp/
. With the current configuration all of the Handlers are routed to the correct url however all of the links used in the templates are wrong. For example
<a href='/'>Home</a>
links to mysite.com/
rather than mysite.com/myapp/
. I'd also like the app to still work locally so I don't want /myapp/
hard-coded into the templates.
Is there a way to deal with this with either nginx or Tornado?
My solution thus far has been to add a convenience function to the template namespace
import tornado.ioloop
import tornado.web
import os
APPLICATION_ROOT = os.environ.get('MYAPP_ROOT')
class BaseHandler(tornado.web.RequestHandler):
def full_url(self, path, *args, **kwargs):
if path.startswith('/'):
path = path.lstrip('/')
return os.path.join(APPLICATION_ROOT, path)
else:
return path
def get_template_namespace(self):
"""Returns a dictionary to be used as the default template namespace.
May be overridden by subclasses to add or modify values.
The results of this method will be combined with additional
defaults in the `tornado.template` module and keyword arguments
to `render` or `render_string`.
"""
namespace = dict(
handler=self,
request=self.request,
current_user=self.current_user,
locale=self.locale,
_=self.locale.translate,
pgettext=self.locale.pgettext,
static_url=self.static_url,
xsrf_form_html=self.xsrf_form_html,
reverse_url=self.reverse_url,
full_url=self.full_url
)
namespace.update(self.ui)
return namespace
and set MYAPP_ROOT='/myapp/'
as an environment variable and use
<a href="{{ full_url('/') }}">Home</a>
in the templates.