kopia lustrzana https://github.com/cirospaciari/socketify.py
add Template support with mako and jinja2 examples
rodzic
0b2908446c
commit
84d849172d
|
@ -30,6 +30,7 @@
|
|||
- Automatic Ping / Pong Support
|
||||
- Per Socket Data
|
||||
- Middlewares
|
||||
- Templates Support (examples with [Mako](https://github.com/cirospaciari/socketify.py/tree/main/examples/template_mako.py) and [Jinja2)](https://github.com/cirospaciari/socketify.py/tree/main/examples/template_jinja2.py))
|
||||
## :mag_right: Upcoming Features
|
||||
- Fetch like API powered by libuv
|
||||
- Async file IO powered by libuv
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
#Simple example of mako and jinja2 template plugin for socketify.py
|
||||
from mako.template import Template
|
||||
from mako.lookup import TemplateLookup
|
||||
from mako import exceptions
|
||||
|
||||
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
|
||||
class Jinja2Template:
|
||||
def __init__(self, searchpath, encoding='utf-8', followlinks=False):
|
||||
self.env = Environment(loader=FileSystemLoader(searchpath, encoding, followlinks))
|
||||
|
||||
#You can also add caching and logging strategy here if you want ;)
|
||||
def render(self, templatename, **kwargs):
|
||||
try:
|
||||
template = self.env.get_template(templatename)
|
||||
return template.render(**kwargs)
|
||||
except Exception as err:
|
||||
return str(err)
|
||||
|
||||
class MakoTemplate:
|
||||
def __init__(self, **options):
|
||||
self.lookup = TemplateLookup(**options)
|
||||
|
||||
#You can also add caching and logging strategy here if you want ;)
|
||||
def render(self, templatename, **kwargs):
|
||||
try:
|
||||
template = self.lookup.get_template(templatename)
|
||||
return template.render(**kwargs)
|
||||
except Exception as err:
|
||||
return exceptions.html_error_template().render()
|
|
@ -3,4 +3,5 @@ aiofiles
|
|||
aiofile
|
||||
redis
|
||||
strawberry-graphql
|
||||
mako
|
||||
git+https://github.com/cirospaciari/socketify.py.git@main#socketify --global-option="build_ext"
|
|
@ -0,0 +1,14 @@
|
|||
from socketify import App
|
||||
#see helper/templates.py for plugin implementation
|
||||
from helpers.templates import Jinja2Template
|
||||
|
||||
|
||||
app = App()
|
||||
app.template(Jinja2Template("./templates", encoding='utf-8', followlinks=False))
|
||||
|
||||
async def home(res, req):
|
||||
res.render("jinja2_home.html", title="Hello", message="Hello, World")
|
||||
|
||||
app.get("/", home)
|
||||
app.listen(3000, lambda config: print("Listening on port http://localhost:%s now\n" % str(config.port)))
|
||||
app.run()
|
|
@ -0,0 +1,14 @@
|
|||
from socketify import App
|
||||
#see helper/templates.py for plugin implementation
|
||||
from helpers.templates import MakoTemplate
|
||||
|
||||
|
||||
app = App()
|
||||
app.template(MakoTemplate(directories=['./templates'], output_encoding='utf-8', encoding_errors='replace'))
|
||||
|
||||
async def home(res, req):
|
||||
res.render("mako_home.html", message="Hello, World")
|
||||
|
||||
app.get("/", home)
|
||||
app.listen(3000, lambda config: print("Listening on port http://localhost:%s now\n" % str(config.port)))
|
||||
app.run()
|
|
@ -0,0 +1,20 @@
|
|||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
|
||||
<head>
|
||||
<title>{{ title }}</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="header">
|
||||
<h1>{{ title }}</h1>
|
||||
</div>
|
||||
|
||||
{%- block body %}{%- endblock %}
|
||||
|
||||
<div id="footer">
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,4 @@
|
|||
{% extends "jinja2_base.html" %}
|
||||
{% block body %}
|
||||
<p>this is the body content. {{ message }}</p>
|
||||
{% endblock body %}
|
|
@ -0,0 +1,15 @@
|
|||
<html>
|
||||
<body>
|
||||
<div class="header">
|
||||
<%block name="header"/>
|
||||
</div>
|
||||
|
||||
${self.body()}
|
||||
|
||||
<div class="footer">
|
||||
<%block name="footer">
|
||||
this is the footer
|
||||
</%block>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,7 @@
|
|||
<%inherit file="mako_base.html"/>
|
||||
|
||||
<%block name="header">
|
||||
this is some header content
|
||||
</%block>
|
||||
|
||||
this is the body content. ${ message }
|
|
@ -422,7 +422,7 @@ def uws_websocket_upgrade_handler(res, req, context, user_data):
|
|||
if not user_data == ffi.NULL:
|
||||
try:
|
||||
(handlers, app) = ffi.from_handle(user_data)
|
||||
response = AppResponse(res, app.loop, app.SSL)
|
||||
response = AppResponse(res, app.loop, app.SSL, app._template)
|
||||
request = AppRequest(req)
|
||||
handler = handlers.upgrade
|
||||
if inspect.iscoroutinefunction(handler):
|
||||
|
@ -463,7 +463,7 @@ def uws_generic_method_handler(res, req, user_data):
|
|||
if not user_data == ffi.NULL:
|
||||
try:
|
||||
(handler, app) = ffi.from_handle(user_data)
|
||||
response = AppResponse(res, app.loop, app.SSL)
|
||||
response = AppResponse(res, app.loop, app.SSL, app._template)
|
||||
request = AppRequest(req)
|
||||
if inspect.iscoroutinefunction(handler):
|
||||
response.grab_aborted_handler()
|
||||
|
@ -1044,7 +1044,7 @@ class AppRequest:
|
|||
self._ptr = ffi.NULL
|
||||
|
||||
class AppResponse:
|
||||
def __init__(self, response, loop, ssl):
|
||||
def __init__(self, response, loop, ssl, render=None):
|
||||
self.res = response
|
||||
self.SSL = ssl
|
||||
self.aborted = False
|
||||
|
@ -1060,6 +1060,7 @@ class AppResponse:
|
|||
self._chunkFuture = None
|
||||
self._dataFuture = None
|
||||
self._data = None
|
||||
self._render = render
|
||||
|
||||
def cork(self, callback):
|
||||
if not self.aborted:
|
||||
|
@ -1253,6 +1254,12 @@ class AppResponse:
|
|||
self.cork(lambda res: res.end(message, end_connection))
|
||||
return self
|
||||
|
||||
def render(self, *args, **kwargs):
|
||||
if self._render:
|
||||
self.cork_end(self._render.render(*args, **kwargs))
|
||||
return self
|
||||
raise RuntimeError("No registered templated engine")
|
||||
|
||||
def get_remote_address_bytes(self):
|
||||
buffer = ffi.new("char**")
|
||||
length = lib.uws_res_get_remote_address(self.SSL, self.res, buffer)
|
||||
|
@ -1467,6 +1474,7 @@ class App:
|
|||
socket_options_ptr = ffi.new("struct us_socket_context_options_t *")
|
||||
socket_options = socket_options_ptr[0]
|
||||
self.options = options
|
||||
self._template = None
|
||||
if options != None:
|
||||
self.is_ssl = True
|
||||
self.SSL = ffi.cast("int", 1)
|
||||
|
@ -1498,7 +1506,9 @@ class App:
|
|||
self._missing_server_handler = None
|
||||
|
||||
|
||||
|
||||
def template(self, template_engine):
|
||||
self._template = template_engine
|
||||
|
||||
def static(self, route, directory):
|
||||
static_route(self, route, directory)
|
||||
return self
|
||||
|
|
Ładowanie…
Reference in New Issue