2

How can you substitute a twisted server variable into the file resource that is served out.

For example, the following code serves up a webpage where i can go and load up ./templates/index.html :

if __name__ == '__main__':
    var = 'my variable'
    from twisted.web.static import File
    webdir = File("{0}/templates/".format(os.path.dirname(os.path.realpath(__file__))))
    web = Site(webdir)
    reactor.listenTCP(int(os.environ.get('SR_LISTEN_PORT')), web)
    reactor.run()

I want the variable 'var' to be substituted for {{variable}} in a basic index.html page

so the page would render 'my variable' instead of hello world for instance.

How can I accomplish this?

user1601716
  • 1,893
  • 4
  • 24
  • 53

1 Answers1

2

It looks like you need a template engine for serving files, you can use jinja2 for it. In your case static.File should be used to render template directory and resource.Resource — to serve files in it rendered via jinja2:

import os

import jinja2

from twisted.internet import reactor
from twisted.web.resource import Resource
from twisted.web.static import File
from twisted.web.server import Site

template_dir = '{}/templates/'.format(os.path.dirname(os.path.realpath(__file__)))

def render(template_file, context):
    env = jinja2.Environment(loader=jinja2.FileSystemLoader(template_dir))
    return env.get_template(template_file).render(context).encode('utf-8')

class RDirectory(File):
    def getChild(self, name, request):
        if name == '':
            return super(RDirectory, self).getChild(name, request)
        return RFile()

class RFile(Resource):
    isLeaf = True

    def render_GET(self, request):
        data = {'var': 'my variable'}
        return render(request.uri, data)

if __name__ == '__main__':
    web = Site(RDirectory(template_dir))
    reactor.listenTCP(int(os.environ.get('SR_LISTEN_PORT')), web)
    reactor.run()

File can be something like this:

<html>
   <head><title>Test</title></head>
   <body>{{ var }}</body>
</html>

Note that jinja2 rendering is a synchronous operation and it will block twisted reactor. To avoid it you can launch rendering in a thread or try to use built-in twisted templates but they do not provide many possibilities.

Community
  • 1
  • 1
Sergey Shubin
  • 3,040
  • 4
  • 24
  • 36
  • This looks like what I need, but never heard of Jinja2 so i'm going to have to do some testing to actually understand the code, thanks! – user1601716 Jan 13 '17 at 15:56
  • @user1601716 Twisted is not very handy as web server so the code looks complicated. If your application will use only HTTP (HTTPS) you may want to try [Tornado](http://www.tornadoweb.org/en/stable/index.html) framework. It is asynchronous too and has a built-in [template system](http://www.tornadoweb.org/en/stable/guide/templates.html) very similar to jinja. But it was designed specifically for web. – Sergey Shubin Jan 14 '17 at 08:16