mirror of
https://github.com/simonw/datasette.git
synced 2025-12-10 16:51:24 +01:00
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:
parent
295d005ca4
commit
4ac9132240
10 changed files with 150 additions and 30 deletions
|
|
@ -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 " "
|
||||
))
|
||||
'''
|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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"}'
|
||||
}]
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue