render_cell(value) plugin hook, closes #352

New plugin hook for customizing the way cells values are rendered in HTML.

The first full example of this hook in use is https://github.com/simonw/datasette-json-html
This commit is contained in:
Simon Willison 2018-08-04 17:14:56 -07:00 committed by GitHub
commit 4ac9132240
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 150 additions and 30 deletions

View file

@ -208,6 +208,8 @@ def extra_js_urls():
PLUGIN2 = '''
from datasette import hookimpl
import jinja2
import json
@hookimpl
@ -216,6 +218,34 @@ def extra_js_urls():
'url': 'https://example.com/jquery.js',
'sri': 'SRIHASH',
}, 'https://example.com/plugin2.js']
@hookimpl
def render_cell(value):
# Render {"href": "...", "label": "..."} as link
if not isinstance(value, str):
return None
stripped = value.strip()
if not stripped.startswith("{") and stripped.endswith("}"):
return None
try:
data = json.loads(value)
except ValueError:
return None
if not isinstance(data, dict):
return None
if set(data.keys()) != {"href", "label"}:
return None
href = data["href"]
if not (
href.startswith("/") or href.startswith("http://")
or href.startswith("https://")
):
return None
return jinja2.Markup('<a href="{href}">{label}</a>'.format(
href=jinja2.escape(data["href"]),
label=jinja2.escape(data["label"] or "") or "&nbsp;"
))
'''
TABLES = '''
@ -363,9 +393,12 @@ INSERT INTO "searchable_fts" (rowid, text1, text2, [name with . and spaces])
CREATE TABLE [select] (
[group] text,
[having] text,
[and] text
[and] text,
[json] text
);
INSERT INTO [select] VALUES ('group', 'having', 'and',
'{"href": "http://example.com/", "label":"Example"}'
);
INSERT INTO [select] VALUES ('group', 'having', 'and');
CREATE TABLE infinity (
value REAL

View file

@ -231,7 +231,7 @@ def test_database_page(app_client):
],
},
}, {
'columns': ['group', 'having', 'and'],
'columns': ['group', 'having', 'and', 'json'],
'name': 'select',
'count': 1,
'hidden': False,
@ -599,6 +599,7 @@ def test_table_with_reserved_word_name(app_client):
'group': 'group',
'having': 'having',
'and': 'and',
'json': '{"href": "http://example.com/", "label":"Example"}'
}]

View file

@ -3,6 +3,7 @@ from .fixtures import ( # noqa
app_client,
)
import pytest
import urllib
def test_plugins_dir_plugin(app_client):
@ -67,3 +68,20 @@ def test_plugins_with_duplicate_js_urls(app_client):
) < srcs.index(
'https://example.com/plugin2.js'
)
def test_plugins_render_cell(app_client):
sql = """
select '{"href": "http://example.com/", "label":"Example"}'
""".strip()
path = "/fixtures?" + urllib.parse.urlencode({
"sql": sql,
})
response = app_client.get(path)
td = Soup(
response.body, "html.parser"
).find("table").find("tbody").find("td")
a = td.find("a")
assert a is not None, str(a)
assert a.attrs["href"] == "http://example.com/"
assert a.text == "Example"