extra_template_vars plugin hook (#542)

* extra_template_vars plugin hook

Closes #541

* Workaround for cwd bug

Based on https://github.com/pytest-dev/pytest/issues/1235#issuecomment-175295691
This commit is contained in:
Simon Willison 2019-07-05 17:05:56 -07:00
commit 42d6877784
9 changed files with 186 additions and 19 deletions

View file

@ -35,6 +35,11 @@ def extra_body_script(template, database, table, view_name, datasette):
"Extra JavaScript code to be included in <script> at bottom of body"
@hookspec
def extra_template_vars(template, database, table, view_name, request, datasette):
"Extra template variables to be made available to the template - can return dict or callable or awaitable"
@hookspec
def publish_subcommand(publish):
"Subcommands for 'datasette publish'"

View file

@ -102,7 +102,7 @@ class BaseView(AsgiView):
def database_color(self, database):
return "ff0000"
def render(self, templates, **context):
async def render(self, templates, request, context):
template = self.ds.jinja_env.select_template(templates)
select_templates = [
"{}{}".format("*" if template_name == template.name else "", template_name)
@ -118,6 +118,26 @@ class BaseView(AsgiView):
datasette=self.ds,
):
body_scripts.append(jinja2.Markup(script))
extra_template_vars = {}
# pylint: disable=no-member
for extra_vars in pm.hook.extra_template_vars(
template=template.name,
database=context.get("database"),
table=context.get("table"),
view_name=self.name,
request=request,
datasette=self.ds,
):
if callable(extra_vars):
extra_vars = extra_vars()
if asyncio.iscoroutine(extra_vars):
extra_vars = await extra_vars
assert isinstance(extra_vars, dict), "extra_vars is of type {}".format(
type(extra_vars)
)
extra_template_vars.update(extra_vars)
return Response.html(
template.render(
{
@ -137,6 +157,7 @@ class BaseView(AsgiView):
"database_url": self.database_url,
"database_color": self.database_color,
},
**extra_template_vars,
}
)
)
@ -471,7 +492,7 @@ class DataView(BaseView):
}
if "metadata" not in context:
context["metadata"] = self.ds.metadata
r = self.render(templates, **context)
r = await self.render(templates, request=request, context=context)
r.status = status_code
ttl = request.args.get("_ttl", None)

View file

@ -109,9 +109,12 @@ class IndexView(BaseView):
headers=headers,
)
else:
return self.render(
return await self.render(
["index.html"],
databases=databases,
metadata=self.ds.metadata(),
datasette_version=__version__,
request=request,
context={
"databases": databases,
"metadata": self.ds.metadata(),
"datasette_version": __version__,
},
)

View file

@ -24,4 +24,8 @@ class JsonDataView(BaseView):
)
else:
return self.render(["show_json.html"], filename=self.filename, data=data)
return await self.render(
["show_json.html"],
request=request,
context={"filename": self.filename, "data": data},
)