Extension that renders templates with Jinja

This commit is contained in:
Miguel Grinberg
2022-07-29 20:19:51 +01:00
parent 7df74b0537
commit 7686b2ae38
11 changed files with 123 additions and 11 deletions

1
.gitignore vendored
View File

@@ -2,6 +2,7 @@
__pycache__/
*.py[cod]
*$py.class
*_html.py
# C extensions
*.so

17
examples/hello_jinja.py Normal file
View File

@@ -0,0 +1,17 @@
from microdot import Microdot, Response
from microdot_jinja import render_template
app = Microdot()
Response.default_content_type = 'text/html'
@app.route('/', methods=['GET', 'POST'])
def index(req):
name = None
if req.method == 'POST':
name = req.form.get('name')
return render_template('index_jinja.html', name=name)
if __name__ == '__main__':
app.run()

View File

@@ -10,7 +10,7 @@ def index(req):
name = None
if req.method == 'POST':
name = req.form.get('name')
return render_template('index.html', name=name)
return render_template('index_utemplate.html', name=name)
if __name__ == '__main__':

View File

@@ -0,0 +1,19 @@
<!doctype html>
<html>
<head>
<title>Microdot + Jinja example</title>
</head>
<body>
<h1>Microdot + Jinja example</h1>
{% if name %}
<p>Hello, <b>{{ name }}</b>!</p>
{% endif %}
<form method="POST">
<p>
What is your name?
<input type="text" name="name" autofocus />
</p>
<input type="submit" value="Submit" />
</form>
</body>
</html>

24
src/microdot_jinja.py Normal file
View File

@@ -0,0 +1,24 @@
from jinja2 import Environment, FileSystemLoader, select_autoescape
_jinja_env = None
def init_templates(template_dir='templates'):
"""Initialize the templating subsystem.
:param template_dir: the directory where templates are stored. This
argument is optional. The default is to load templates
from a *templates* subdirectory.
"""
global _jinja_env
_jinja_env = Environment(
loader=FileSystemLoader(template_dir),
autoescape=select_autoescape()
)
def render_template(template, *args, **kwargs):
if _jinja_env is None: # pragma: no cover
init_templates()
template = _jinja_env.get_template(template)
return template.render(*args, **kwargs)

View File

@@ -23,7 +23,3 @@ def render_template(template, *args, **kwargs):
init_templates()
render = _loader.load(template)
return render(*args, **kwargs)
def render_template_string(template, *args, **kwargs):
return ''.join(render_template(template, *args, **kwargs))

View File

@@ -0,0 +1 @@
Hello, {{ name }}!

View File

@@ -0,0 +1,58 @@
try:
import uasyncio as asyncio
except ImportError:
import asyncio
import sys
import unittest
from microdot import Microdot, Request
from microdot_asyncio import Microdot as MicrodotAsync, Request as RequestAsync
from microdot_jinja import render_template, init_templates
from tests.mock_socket import get_request_fd, get_async_request_fd
init_templates('tests/microdot_jinja/templates')
def _run(coro):
return asyncio.get_event_loop().run_until_complete(coro)
@unittest.skipIf(sys.implementation.name == 'micropython',
'not supported under MicroPython')
class TestUTemplate(unittest.TestCase):
def test_render_template(self):
s = render_template('hello.txt', name='foo')
self.assertEqual(s, 'Hello, foo!')
def test_render_template_in_app(self):
app = Microdot()
@app.route('/')
def index(req):
return render_template('hello.txt', name='foo')
req = Request.create(app, get_request_fd('GET', '/'), 'addr')
res = app.dispatch_request(req)
self.assertEqual(res.status_code, 200)
self.assertEqual(list(res.body_iter()), [b'Hello, foo!'])
def test_render_template_in_app_async(self):
app = MicrodotAsync()
@app.route('/')
async def index(req):
return render_template('hello.txt', name='foo')
req = _run(RequestAsync.create(
app, get_async_request_fd('GET', '/'), 'addr'))
res = _run(app.dispatch_request(req))
self.assertEqual(res.status_code, 200)
async def get_result():
result = []
async for chunk in res.body_iter():
result.append(chunk)
return result
result = _run(get_result())
self.assertEqual(result, [b'Hello, foo!'])

View File

@@ -6,8 +6,7 @@ except ImportError:
import unittest
from microdot import Microdot, Request
from microdot_asyncio import Microdot as MicrodotAsync, Request as RequestAsync
from microdot_utemplate import render_template, render_template_string, \
init_templates
from microdot_utemplate import render_template, init_templates
from tests.mock_socket import get_request_fd, get_async_request_fd
init_templates('tests/microdot_utemplate/templates')
@@ -22,10 +21,6 @@ class TestUTemplate(unittest.TestCase):
s = list(render_template('hello.txt', name='foo'))
self.assertEqual(s, ['Hello, ', 'foo', '!\n'])
def test_render_template_string(self):
s = render_template_string('hello.txt', name='foo')
self.assertEqual(s.strip(), 'Hello, foo!')
def test_render_template_in_app(self):
app = Microdot()

View File

@@ -19,6 +19,7 @@ commands=
deps=
pytest
pytest-cov
jinja2
setenv=
PYTHONPATH=libs/common