Apply render_cell plugin on table views, refs #352

This commit is contained in:
Simon Willison 2018-08-04 17:04:53 -07:00
commit 61e9a4d601
No known key found for this signature in database
GPG key ID: 17E2DEA2588B7F52
6 changed files with 19 additions and 24 deletions

View file

@ -2,7 +2,6 @@ import asyncio
import click import click
import collections import collections
import hashlib import hashlib
import importlib
import itertools import itertools
import os import os
import sqlite3 import sqlite3
@ -14,7 +13,6 @@ from concurrent import futures
from pathlib import Path from pathlib import Path
from markupsafe import Markup from markupsafe import Markup
import pluggy
from jinja2 import ChoiceLoader, Environment, FileSystemLoader, PrefixLoader from jinja2 import ChoiceLoader, Environment, FileSystemLoader, PrefixLoader
from sanic import Sanic, response from sanic import Sanic, response
from sanic.exceptions import InvalidUsage, NotFound from sanic.exceptions import InvalidUsage, NotFound
@ -28,7 +26,6 @@ from .views.index import IndexView
from .views.special import JsonDataView from .views.special import JsonDataView
from .views.table import RowView, TableView from .views.table import RowView, TableView
from . import hookspecs
from .utils import ( from .utils import (
InterruptedError, InterruptedError,
Results, Results,
@ -40,26 +37,13 @@ from .utils import (
to_css_class to_css_class
) )
from .inspect import inspect_hash, inspect_views, inspect_tables from .inspect import inspect_hash, inspect_views, inspect_tables
from .plugins import pm
from .version import __version__ from .version import __version__
default_plugins = (
"datasette.publish.heroku",
"datasette.publish.now",
)
app_root = Path(__file__).parent.parent app_root = Path(__file__).parent.parent
connections = threading.local() connections = threading.local()
pm = pluggy.PluginManager("datasette")
pm.add_hookspecs(hookspecs)
pm.load_setuptools_entrypoints("datasette")
# Load default plugins
for plugin in default_plugins:
mod = importlib.import_module(plugin)
pm.register(mod, plugin)
ConfigOption = collections.namedtuple( ConfigOption = collections.namedtuple(
"ConfigOption", ("name", "default", "help") "ConfigOption", ("name", "default", "help")

View file

@ -16,7 +16,6 @@ import shutil
import urllib import urllib
import numbers import numbers
# From https://www.sqlite.org/lang_keywords.html # From https://www.sqlite.org/lang_keywords.html
reserved_words = set(( reserved_words = set((
'abort action add after all alter analyze and as asc attach autoincrement ' 'abort action add after all alter analyze and as asc attach autoincrement '

View file

@ -13,6 +13,7 @@ from sanic.exceptions import NotFound
from sanic.views import HTTPMethodView from sanic.views import HTTPMethodView
from datasette import __version__ from datasette import __version__
from datasette.plugins import pm
from datasette.utils import ( from datasette.utils import (
CustomJSONEncoder, CustomJSONEncoder,
InterruptedError, InterruptedError,
@ -494,7 +495,6 @@ class BaseView(RenderMixin):
for value in row: for value in row:
display_value = value display_value = value
# Let the plugins have a go # Let the plugins have a go
from datasette.app import pm
plugin_value = pm.hook.render_cell(value=value) plugin_value = pm.hook.render_cell(value=value)
if plugin_value is not None: if plugin_value is not None:
display_value = plugin_value display_value = plugin_value

View file

@ -5,6 +5,7 @@ import jinja2
from sanic.exceptions import NotFound from sanic.exceptions import NotFound
from sanic.request import RequestParameters from sanic.request import RequestParameters
from datasette.plugins import pm
from datasette.utils import ( from datasette.utils import (
CustomRow, CustomRow,
Filters, Filters,
@ -22,7 +23,6 @@ from datasette.utils import (
urlsafe_components, urlsafe_components,
value_as_boolean, value_as_boolean,
) )
from .base import BaseView, DatasetteError, ureg from .base import BaseView, DatasetteError, ureg
LINK_WITH_LABEL = '<a href="/{database}/{table}/{link_id}">{label}</a>&nbsp;<em>{id}</em>' LINK_WITH_LABEL = '<a href="/{database}/{table}/{link_id}">{label}</a>&nbsp;<em>{id}</em>'
@ -166,7 +166,11 @@ class RowTableShared(BaseView):
# already shown in the link column. # already shown in the link column.
continue continue
if isinstance(value, dict): # First let the plugins have a go
plugin_display_value = pm.hook.render_cell(value=value)
if plugin_display_value is not None:
display_value = plugin_display_value
elif isinstance(value, dict):
# It's an expanded foreign key - display link to other row # It's an expanded foreign key - display link to other row
label = value["label"] label = value["label"]
value = value["value"] value = value["value"]

View file

@ -223,6 +223,8 @@ def extra_js_urls():
@hookimpl @hookimpl
def render_cell(value): def render_cell(value):
# Render {"href": "...", "label": "..."} as link # Render {"href": "...", "label": "..."} as link
if not isinstance(value, str):
return None
stripped = value.strip() stripped = value.strip()
if not stripped.startswith("{") and stripped.endswith("}"): if not stripped.startswith("{") and stripped.endswith("}"):
return None return None
@ -230,6 +232,8 @@ def render_cell(value):
data = json.loads(value) data = json.loads(value)
except ValueError: except ValueError:
return None return None
if not isinstance(data, dict):
return None
if set(data.keys()) != {"href", "label"}: if set(data.keys()) != {"href", "label"}:
return None return None
href = data["href"] href = data["href"]
@ -389,9 +393,12 @@ INSERT INTO "searchable_fts" (rowid, text1, text2, [name with . and spaces])
CREATE TABLE [select] ( CREATE TABLE [select] (
[group] text, [group] text,
[having] 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 ( CREATE TABLE infinity (
value REAL 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', 'name': 'select',
'count': 1, 'count': 1,
'hidden': False, 'hidden': False,
@ -599,6 +599,7 @@ def test_table_with_reserved_word_name(app_client):
'group': 'group', 'group': 'group',
'having': 'having', 'having': 'having',
'and': 'and', 'and': 'and',
'json': '{"href": "http://example.com/", "label":"Example"}'
}] }]