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
|
|
@ -2,7 +2,6 @@ import asyncio
|
|||
import click
|
||||
import collections
|
||||
import hashlib
|
||||
import importlib
|
||||
import itertools
|
||||
import os
|
||||
import sqlite3
|
||||
|
|
@ -14,7 +13,6 @@ from concurrent import futures
|
|||
from pathlib import Path
|
||||
|
||||
from markupsafe import Markup
|
||||
import pluggy
|
||||
from jinja2 import ChoiceLoader, Environment, FileSystemLoader, PrefixLoader
|
||||
from sanic import Sanic, response
|
||||
from sanic.exceptions import InvalidUsage, NotFound
|
||||
|
|
@ -28,7 +26,6 @@ from .views.index import IndexView
|
|||
from .views.special import JsonDataView
|
||||
from .views.table import RowView, TableView
|
||||
|
||||
from . import hookspecs
|
||||
from .utils import (
|
||||
InterruptedError,
|
||||
Results,
|
||||
|
|
@ -40,26 +37,13 @@ from .utils import (
|
|||
to_css_class
|
||||
)
|
||||
from .inspect import inspect_hash, inspect_views, inspect_tables
|
||||
from .plugins import pm
|
||||
from .version import __version__
|
||||
|
||||
default_plugins = (
|
||||
"datasette.publish.heroku",
|
||||
"datasette.publish.now",
|
||||
)
|
||||
|
||||
app_root = Path(__file__).parent.parent
|
||||
|
||||
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", ("name", "default", "help")
|
||||
|
|
|
|||
|
|
@ -28,3 +28,8 @@ def extra_js_urls():
|
|||
@hookspec
|
||||
def publish_subcommand(publish):
|
||||
"Subcommands for 'datasette publish'"
|
||||
|
||||
|
||||
@hookspec(firstresult=True)
|
||||
def render_cell(value):
|
||||
"Customize rendering of HTML table cell values"
|
||||
|
|
|
|||
17
datasette/plugins.py
Normal file
17
datasette/plugins.py
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import importlib
|
||||
import pluggy
|
||||
from . import hookspecs
|
||||
|
||||
default_plugins = (
|
||||
"datasette.publish.heroku",
|
||||
"datasette.publish.now",
|
||||
)
|
||||
|
||||
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)
|
||||
|
|
@ -16,7 +16,6 @@ import shutil
|
|||
import urllib
|
||||
import numbers
|
||||
|
||||
|
||||
# From https://www.sqlite.org/lang_keywords.html
|
||||
reserved_words = set((
|
||||
'abort action add after all alter analyze and as asc attach autoincrement '
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ from sanic.exceptions import NotFound
|
|||
from sanic.views import HTTPMethodView
|
||||
|
||||
from datasette import __version__
|
||||
from datasette.plugins import pm
|
||||
from datasette.utils import (
|
||||
CustomJSONEncoder,
|
||||
InterruptedError,
|
||||
|
|
@ -493,14 +494,19 @@ class BaseView(RenderMixin):
|
|||
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(
|
||||
'<a href="{url}">{url}</a>'.format(
|
||||
url=jinja2.escape(value.strip())
|
||||
# Let the plugins have a go
|
||||
plugin_value = pm.hook.render_cell(value=value)
|
||||
if plugin_value is not None:
|
||||
display_value = plugin_value
|
||||
else:
|
||||
if value in ("", None):
|
||||
display_value = jinja2.Markup(" ")
|
||||
elif is_url(str(display_value).strip()):
|
||||
display_value = jinja2.Markup(
|
||||
'<a href="{url}">{url}</a>'.format(
|
||||
url=jinja2.escape(value.strip())
|
||||
)
|
||||
)
|
||||
)
|
||||
display_row.append(display_value)
|
||||
display_rows.append(display_row)
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import jinja2
|
|||
from sanic.exceptions import NotFound
|
||||
from sanic.request import RequestParameters
|
||||
|
||||
from datasette.plugins import pm
|
||||
from datasette.utils import (
|
||||
CustomRow,
|
||||
Filters,
|
||||
|
|
@ -22,7 +23,6 @@ from datasette.utils import (
|
|||
urlsafe_components,
|
||||
value_as_boolean,
|
||||
)
|
||||
|
||||
from .base import BaseView, DatasetteError, ureg
|
||||
|
||||
LINK_WITH_LABEL = '<a href="/{database}/{table}/{link_id}">{label}</a> <em>{id}</em>'
|
||||
|
|
@ -166,7 +166,11 @@ class RowTableShared(BaseView):
|
|||
# already shown in the link column.
|
||||
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
|
||||
label = value["label"]
|
||||
value = value["value"]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue