mirror of
https://github.com/simonw/datasette.git
synced 2025-12-10 16:51:24 +01:00
WIP table_filter plugin hook
This commit is contained in:
parent
4ac9132240
commit
5116c4ec8a
4 changed files with 48 additions and 5 deletions
|
|
@ -33,3 +33,8 @@ def publish_subcommand(publish):
|
||||||
@hookspec(firstresult=True)
|
@hookspec(firstresult=True)
|
||||||
def render_cell(value):
|
def render_cell(value):
|
||||||
"Customize rendering of HTML table cell values"
|
"Customize rendering of HTML table cell values"
|
||||||
|
|
||||||
|
|
||||||
|
@hookspec
|
||||||
|
def table_filter():
|
||||||
|
"Custom filtering of the current table based on the request"
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict, namedtuple
|
||||||
import base64
|
import base64
|
||||||
import click
|
import click
|
||||||
import hashlib
|
import hashlib
|
||||||
|
|
@ -39,6 +39,10 @@ RUN apt-get update && \
|
||||||
ENV SQLITE_EXTENSIONS /usr/lib/x86_64-linux-gnu/mod_spatialite.so
|
ENV SQLITE_EXTENSIONS /usr/lib/x86_64-linux-gnu/mod_spatialite.so
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
TableFilter = namedtuple("TableFilter", (
|
||||||
|
"human_description_extras", "where_clauses", "params")
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class InterruptedError(Exception):
|
class InterruptedError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
|
||||||
|
|
@ -313,7 +313,7 @@ class TableView(RowTableShared):
|
||||||
search_args = dict(
|
search_args = dict(
|
||||||
pair for pair in special_args.items() if pair[0].startswith("_search")
|
pair for pair in special_args.items() if pair[0].startswith("_search")
|
||||||
)
|
)
|
||||||
search_descriptions = []
|
human_description_extras = []
|
||||||
search = ""
|
search = ""
|
||||||
if fts_table and search_args:
|
if fts_table and search_args:
|
||||||
if "_search" in search_args:
|
if "_search" in search_args:
|
||||||
|
|
@ -324,7 +324,7 @@ class TableView(RowTableShared):
|
||||||
fts_table=escape_sqlite(fts_table),
|
fts_table=escape_sqlite(fts_table),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
search_descriptions.append('search matches "{}"'.format(search))
|
human_description_extras.append('search matches "{}"'.format(search))
|
||||||
params["search"] = search
|
params["search"] = search
|
||||||
else:
|
else:
|
||||||
# More complex: search against specific columns
|
# More complex: search against specific columns
|
||||||
|
|
@ -341,13 +341,22 @@ class TableView(RowTableShared):
|
||||||
i=i
|
i=i
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
search_descriptions.append(
|
human_description_extras.append(
|
||||||
'search column "{}" matches "{}"'.format(
|
'search column "{}" matches "{}"'.format(
|
||||||
search_col, search_text
|
search_col, search_text
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
params["search_{}".format(i)] = search_text
|
params["search_{}".format(i)] = search_text
|
||||||
|
|
||||||
|
# filter_arguments plugin hook support
|
||||||
|
for awaitable_fn in pm.hook.table_filter():
|
||||||
|
extras = await awaitable_fn(
|
||||||
|
view=self, name=name, table=table, request=request
|
||||||
|
)
|
||||||
|
human_description_extras.extend(extras.human_description_extras)
|
||||||
|
where_clauses.extend(extras.where_clauses)
|
||||||
|
params.update(extras.params)
|
||||||
|
|
||||||
table_rows_count = None
|
table_rows_count = None
|
||||||
sortable_columns = set()
|
sortable_columns = set()
|
||||||
if not is_view:
|
if not is_view:
|
||||||
|
|
@ -713,7 +722,7 @@ class TableView(RowTableShared):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# human_description_en combines filters AND search, if provided
|
# human_description_en combines filters AND search, if provided
|
||||||
human_description_en = filters.human_description_en(extra=search_descriptions)
|
human_description_en = filters.human_description_en(extra=human_description_extras)
|
||||||
|
|
||||||
if sort or sort_desc:
|
if sort or sort_desc:
|
||||||
sorted_by = "sorted by {}{}".format(
|
sorted_by = "sorted by {}{}".format(
|
||||||
|
|
|
||||||
|
|
@ -320,3 +320,28 @@ If the value matches that pattern, the plugin returns an HTML link element:
|
||||||
href=jinja2.escape(data["href"]),
|
href=jinja2.escape(data["href"]),
|
||||||
label=jinja2.escape(data["label"] or "") or " "
|
label=jinja2.escape(data["label"] or "") or " "
|
||||||
))
|
))
|
||||||
|
|
||||||
|
table_filter
|
||||||
|
~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Apply additional SQL filters to the current table based on the request.
|
||||||
|
|
||||||
|
This should return an awaitable function with the following signature:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
from datasette.utils import TableFilter
|
||||||
|
|
||||||
|
@hookimpl
|
||||||
|
def table_filter():
|
||||||
|
async def inner(view, name, table, request):
|
||||||
|
extra_human_descriptions = []
|
||||||
|
where_clauses = []
|
||||||
|
params = {}
|
||||||
|
# ... build those things here
|
||||||
|
return TableFilter(
|
||||||
|
human_description_extras=extra_human_descriptions,
|
||||||
|
where_clauses=where_clauses,
|
||||||
|
params=params,
|
||||||
|
)
|
||||||
|
return inner
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue