From 2aaad72789c427875426673c1a43e67c86fc970e Mon Sep 17 00:00:00 2001 From: Simon Willison Date: Thu, 26 Mar 2020 18:12:43 -0700 Subject: [PATCH] Refactor template setup into Datasette constructor Closes #707 --- datasette/app.py | 65 +++++++++++++++++++++++----------------------- docs/internals.rst | 2 +- tests/fixtures.py | 4 +-- 3 files changed, 36 insertions(+), 35 deletions(-) diff --git a/datasette/app.py b/datasette/app.py index 011002ee..e8496abf 100644 --- a/datasette/app.py +++ b/datasette/app.py @@ -211,6 +211,39 @@ class Datasette: # Plugin already registered pass + # Configure Jinja + default_templates = str(app_root / "datasette" / "templates") + template_paths = [] + if self.template_dir: + template_paths.append(self.template_dir) + plugin_template_paths = [ + plugin["templates_path"] + for plugin in get_plugins() + if plugin["templates_path"] + ] + template_paths.extend(plugin_template_paths) + template_paths.append(default_templates) + template_loader = ChoiceLoader( + [ + FileSystemLoader(template_paths), + # Support {% extends "default:table.html" %}: + PrefixLoader( + {"default": FileSystemLoader(default_templates)}, delimiter=":" + ), + ] + ) + self.jinja_env = Environment( + loader=template_loader, autoescape=True, enable_async=True + ) + self.jinja_env.filters["escape_css_string"] = escape_css_string + self.jinja_env.filters["quote_plus"] = lambda u: urllib.parse.quote_plus(u) + self.jinja_env.filters["escape_sqlite"] = escape_sqlite + self.jinja_env.filters["to_css_class"] = to_css_class + # pylint: disable=no-member + pm.hook.prepare_jinja2_environment(env=self.jinja_env) + + self.register_renderers() + def add_database(self, name, db): self.databases[name] = db @@ -611,38 +644,6 @@ class Datasette: def app(self): "Returns an ASGI app function that serves the whole of Datasette" - default_templates = str(app_root / "datasette" / "templates") - template_paths = [] - if self.template_dir: - template_paths.append(self.template_dir) - plugin_template_paths = [ - plugin["templates_path"] - for plugin in get_plugins() - if plugin["templates_path"] - ] - template_paths.extend(plugin_template_paths) - template_paths.append(default_templates) - template_loader = ChoiceLoader( - [ - FileSystemLoader(template_paths), - # Support {% extends "default:table.html" %}: - PrefixLoader( - {"default": FileSystemLoader(default_templates)}, delimiter=":" - ), - ] - ) - self.jinja_env = Environment( - loader=template_loader, autoescape=True, enable_async=True - ) - self.jinja_env.filters["escape_css_string"] = escape_css_string - self.jinja_env.filters["quote_plus"] = lambda u: urllib.parse.quote_plus(u) - self.jinja_env.filters["escape_sqlite"] = escape_sqlite - self.jinja_env.filters["to_css_class"] = to_css_class - # pylint: disable=no-member - pm.hook.prepare_jinja2_environment(env=self.jinja_env) - - self.register_renderers() - routes = [] def add_route(view, regex): diff --git a/docs/internals.rst b/docs/internals.rst index a68a73b1..d7b6e7cb 100644 --- a/docs/internals.rst +++ b/docs/internals.rst @@ -36,7 +36,7 @@ This method lets you read plugin configuration values that were set in ``metadat ``template`` - string The template file to be rendered, e.g. ``my_plugin.html``. Datasette will search for this file first in the ``--template-dir=`` location, if it was specified - then in the plugin's bundled templates and finally in Datasette's set of default templates. -``conttext`` - None or a Python dictionary +``context`` - None or a Python dictionary The context variables to pass to the template. ``request`` - request object or None diff --git a/tests/fixtures.py b/tests/fixtures.py index 2ea40138..e0b56afe 100644 --- a/tests/fixtures.py +++ b/tests/fixtures.py @@ -406,7 +406,7 @@ def extra_template_vars(template, database, table, view_name, request, datasette return { "extra_template_vars": json.dumps({ "template": template, - "scope_path": request.scope["path"] + "scope_path": request.scope["path"] if request else None }, default=lambda b: b.decode("utf8")) } """ @@ -468,7 +468,7 @@ def extra_template_vars(template, database, table, view_name, request, datasette return { "extra_template_vars_from_awaitable": json.dumps({ "template": template, - "scope_path": request.scope["path"], + "scope_path": request.scope["path"] if request else None, "awaitable": True, }, default=lambda b: b.decode("utf8")), "query_database": query_database,