diff --git a/datasette/templates/query.html b/datasette/templates/query.html index 2fb461a1..b23c67d8 100644 --- a/datasette/templates/query.html +++ b/datasette/templates/query.html @@ -26,7 +26,7 @@ {% block description_source_license %}{% include "_description_source_license.html" %}{% endblock %}
-{% if rows %} +{% if display_rows %}| {% if td == None %}{{ " "|safe }}{% else %}{{ td }}{% endif %} | diff --git a/datasette/views/base.py b/datasette/views/base.py index 3da3793c..45bc8183 100644 --- a/datasette/views/base.py +++ b/datasette/views/base.py @@ -6,6 +6,7 @@ import sqlite3 import time import urllib +import jinja2 import pint from sanic import response from sanic.exceptions import NotFound @@ -17,6 +18,7 @@ from datasette.utils import ( InterruptedError, InvalidSql, LimitedWriter, + is_url, path_from_row_pks, path_with_added_args, path_with_format, @@ -485,21 +487,40 @@ class BaseView(RenderMixin): ), ) + async def extra_template(): + display_rows = [] + for row in results.rows: + display_row = [] + for value in row: + display_value = value + if value in ("", None): + display_value = jinja2.Markup(" ") + elif is_url(str(value).strip()): + display_value = jinja2.Markup( + '{url}'.format( + url=jinja2.escape(value.strip()) + ) + ) + display_row.append(display_value) + display_rows.append(display_row) + return { + "display_rows": display_rows, + "database_hash": hash, + "custom_sql": True, + "named_parameter_values": named_parameter_values, + "editable": editable, + "canned_query": canned_query, + "metadata": metadata, + "config": self.ds.config, + } + return { "database": name, "rows": results.rows, "truncated": results.truncated, "columns": columns, "query": {"sql": sql, "params": params}, - }, { - "database_hash": hash, - "custom_sql": True, - "named_parameter_values": named_parameter_values, - "editable": editable, - "canned_query": canned_query, - "metadata": metadata, - "config": self.ds.config, - }, templates + }, extra_template, templates def convert_specific_columns_to_json(rows, columns, json_cols): diff --git a/tests/test_html.py b/tests/test_html.py index 0b920fff..5f59f61a 100644 --- a/tests/test_html.py +++ b/tests/test_html.py @@ -793,3 +793,17 @@ def test_advanced_export_box(app_client, path, has_object, has_stream, has_expan # "expand labels" option if has_expand: assert "expand labels" in str(div) + + +def test_urlify_custom_queries(app_client): + path = "/fixtures?" + urllib.parse.urlencode({ + "sql": "select ('https://twitter.com/' || 'simonw') as user_url;" + }) + response = app_client.get(path) + assert response.status == 200 + soup = Soup(response.body, "html.parser") + assert '''+ + https://twitter.com/simonw + + | ''' == soup.find("td", {"class": "col-user_url"}).prettify().strip()