diff --git a/.travis.yml b/.travis.yml index 0fc87d931c..1066608527 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,7 +27,7 @@ jobs: - npm install -g now - python tests/fixtures.py fixtures.db fixtures.json - export ALIAS=`echo $TRAVIS_COMMIT | cut -c 1-7` - - datasette publish nowv1 fixtures.db -m fixtures.json --token=$NOW_TOKEN --branch=$TRAVIS_COMMIT --version-note=$TRAVIS_COMMIT --name=datasette-latest-$ALIAS --alias=latest.datasette.io --alias=$ALIAS.datasette.io + - datasette publish nowv1 fixtures.db -m fixtures.json --token=$NOW_TOKEN --branch=$TRAVIS_COMMIT --version-note=$TRAVIS_COMMIT --name=datasette-latest-$ALIAS --alias=latest.datasette.io --alias=$ALIAS.datasette.io --extra-options='--config template_debug:1' - stage: release tagged version if: tag IS present python: 3.6 diff --git a/datasette/app.py b/datasette/app.py index 2065e356a8..f6b3e51443 100644 --- a/datasette/app.py +++ b/datasette/app.py @@ -126,6 +126,11 @@ False, "Force URLs in API output to always use https:// protocol", ), + ConfigOption( + "template_debug", + False, + "Allow display of template debug information with ?_context=1", + ), ) DEFAULT_CONFIG = {option.name: option.default for option in CONFIG_OPTIONS} diff --git a/datasette/views/base.py b/datasette/views/base.py index 5182479cfd..61561a329f 100644 --- a/datasette/views/base.py +++ b/datasette/views/base.py @@ -1,6 +1,7 @@ import asyncio import csv import itertools +import json import re import time import urllib @@ -138,29 +139,28 @@ async def render(self, templates, request, context): ) extra_template_vars.update(extra_vars) - return Response.html( - await template.render_async( - { - **context, - **{ - "app_css_hash": self.ds.app_css_hash(), - "select_templates": select_templates, - "zip": zip, - "body_scripts": body_scripts, - "extra_css_urls": self._asset_urls( - "extra_css_urls", template, context - ), - "extra_js_urls": self._asset_urls( - "extra_js_urls", template, context - ), - "format_bytes": format_bytes, - "database_url": self.database_url, - "database_color": self.database_color, - }, - **extra_template_vars, - } + template_context = { + **context, + **{ + "app_css_hash": self.ds.app_css_hash(), + "select_templates": select_templates, + "zip": zip, + "body_scripts": body_scripts, + "extra_css_urls": self._asset_urls("extra_css_urls", template, context), + "extra_js_urls": self._asset_urls("extra_js_urls", template, context), + "format_bytes": format_bytes, + "database_url": self.database_url, + "database_color": self.database_color, + }, + **extra_template_vars, + } + if request.args.get("_context") and self.ds.config("template_debug"): + return Response.html( + "
{}".format( + escape(json.dumps(template_context, default=repr, indent=4)) + ) ) - ) + return Response.html(await template.render_async(template_context)) class DataView(BaseView): diff --git a/docs/config.rst b/docs/config.rst index 25924593e5..199d9455b4 100644 --- a/docs/config.rst +++ b/docs/config.rst @@ -209,3 +209,22 @@ itself will result in new, uncachcacheed URL paths. :: datasette mydatabase.db --config hash_urls:1 + +.. _config_template_debug: + +template_debug +-------------- + +This setting enables template context debug mode, which is useful to help understand what variables are available to custom templates when you are writing them. + +Enable it like this:: + + datasette mydatabase.db --config template_debug:1 + +Now you can add ``?_context=1`` or ``&_context=1`` to any Datasette page to see the context that was passed to that template. + +Some examples: + +* https://latest.datasette.io/?_context=1 +* https://latest.datasette.io/fixtures?_context=1 +* https://latest.datasette.io/fixtures/roadside_attractions?_context=1 diff --git a/tests/test_api.py b/tests/test_api.py index cf09c1bace..979ee9bfa1 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -1287,6 +1287,7 @@ def test_config_json(app_client): "truncate_cells_html": 2048, "force_https_urls": False, "hash_urls": False, + "template_debug": False, } == response.json diff --git a/tests/test_html.py b/tests/test_html.py index db73da18c0..823d7c9a4d 100644 --- a/tests/test_html.py +++ b/tests/test_html.py @@ -1073,3 +1073,16 @@ def test_zero_results(app_client, path): soup = Soup(response.text, "html.parser") assert 0 == len(soup.select("table")) assert 1 == len(soup.select("p.zero-results")) + + +def test_config_template_debug_on(): + for client in make_app_client(config={"template_debug": True}): + response = client.get("/fixtures/facetable?_context=1") + assert response.status == 200 + assert response.text.startswith("
{") + + +def test_config_template_debug_off(app_client): + response = app_client.get("/fixtures/facetable?_context=1") + assert response.status == 200 + assert not response.text.startswith("{")