mirror of
https://github.com/simonw/datasette.git
synced 2026-05-28 04:46:18 +02:00
Add pks parameter to render_cell() plugin hook
The render_cell() hook now receives a pks parameter containing the list of primary key column names for the table being rendered. This avoids plugins needing to make redundant async calls to look up primary keys. For tables without an explicit primary key, pks is ["rowid"]. For custom SQL queries and views, pks is an empty list []. https://claude.ai/code/session_01HFYfevAziq4fSYTNRD9ZCh
This commit is contained in:
parent
8a315f3d7d
commit
170f9de774
8 changed files with 62 additions and 5 deletions
|
|
@ -55,7 +55,7 @@ def publish_subcommand(publish):
|
|||
|
||||
|
||||
@hookspec
|
||||
def render_cell(row, value, column, table, database, datasette, request):
|
||||
def render_cell(row, value, column, table, pks, database, datasette, request):
|
||||
"""Customize rendering of HTML table cell values"""
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1205,6 +1205,7 @@ async def display_rows(datasette, database, request, rows, columns):
|
|||
value=value,
|
||||
column=column,
|
||||
table=None,
|
||||
pks=[],
|
||||
database=database,
|
||||
datasette=datasette,
|
||||
request=request,
|
||||
|
|
|
|||
|
|
@ -130,6 +130,7 @@ class RowView(DataView):
|
|||
value=value,
|
||||
column=column,
|
||||
table=table,
|
||||
pks=resolved.pks,
|
||||
database=database,
|
||||
datasette=self.ds,
|
||||
request=request,
|
||||
|
|
|
|||
|
|
@ -235,6 +235,7 @@ async def display_columns_and_rows(
|
|||
value=value,
|
||||
column=column,
|
||||
table=table_name,
|
||||
pks=pks_for_display,
|
||||
database=database_name,
|
||||
datasette=datasette,
|
||||
request=request,
|
||||
|
|
@ -1494,6 +1495,7 @@ async def table_view_data(
|
|||
|
||||
async def extra_render_cell():
|
||||
"Rendered HTML for each cell using the render_cell plugin hook"
|
||||
pks_for_display = pks if pks else (["rowid"] if not is_view else [])
|
||||
columns = [col[0] for col in results.description]
|
||||
rendered_rows = []
|
||||
for row in rows:
|
||||
|
|
@ -1506,6 +1508,7 @@ async def table_view_data(
|
|||
value=value,
|
||||
column=column,
|
||||
table=table_name,
|
||||
pks=pks_for_display,
|
||||
database=database_name,
|
||||
datasette=datasette,
|
||||
request=request,
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ Each plugin can implement one or more hooks using the ``@hookimpl`` decorator ag
|
|||
|
||||
When you implement a plugin hook you can accept any or all of the parameters that are documented as being passed to that hook.
|
||||
|
||||
For example, you can implement the ``render_cell`` plugin hook like this even though the full documented hook signature is ``render_cell(row, value, column, table, database, datasette)``:
|
||||
For example, you can implement the ``render_cell`` plugin hook like this even though the full documented hook signature is ``render_cell(row, value, column, table, pks, database, datasette, request)``:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
|
|
@ -474,8 +474,8 @@ Examples: `datasette-publish-fly <https://datasette.io/plugins/datasette-publish
|
|||
|
||||
.. _plugin_hook_render_cell:
|
||||
|
||||
render_cell(row, value, column, table, database, datasette, request)
|
||||
--------------------------------------------------------------------
|
||||
render_cell(row, value, column, table, pks, database, datasette, request)
|
||||
-------------------------------------------------------------------------
|
||||
|
||||
Lets you customize the display of values within table cells in the HTML table view.
|
||||
|
||||
|
|
@ -491,6 +491,9 @@ Lets you customize the display of values within table cells in the HTML table vi
|
|||
``table`` - string or None
|
||||
The name of the table - or ``None`` if this is a custom SQL query
|
||||
|
||||
``pks`` - list of strings
|
||||
The primary key column names for the table being rendered. For tables without an explicitly defined primary key, this will be ``["rowid"]``. For custom SQL queries and views (where ``table`` is ``None``), this will be an empty list ``[]``.
|
||||
|
||||
``database`` - string
|
||||
The name of the database
|
||||
|
||||
|
|
|
|||
|
|
@ -428,6 +428,7 @@ CREATE TABLE compound_primary_key (
|
|||
|
||||
INSERT INTO compound_primary_key VALUES ('a', 'b', 'c');
|
||||
INSERT INTO compound_primary_key VALUES ('a/b', '.c-d', 'c');
|
||||
INSERT INTO compound_primary_key VALUES ('d', 'e', 'RENDER_CELL_DEMO');
|
||||
|
||||
CREATE TABLE compound_three_primary_keys (
|
||||
pk1 varchar(30),
|
||||
|
|
@ -700,6 +701,7 @@ CREATE VIEW searchable_view_configured_by_metadata AS
|
|||
for i in range(201)
|
||||
]
|
||||
)
|
||||
+ '\nINSERT INTO no_primary_key VALUES ("RENDER_CELL_DEMO", "a202", "b202", "c202");\n'
|
||||
+ "\n".join(
|
||||
[
|
||||
'INSERT INTO compound_three_primary_keys VALUES ("{a}", "{b}", "{c}", "{content}");'.format(
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ def extra_body_script(
|
|||
|
||||
|
||||
@hookimpl
|
||||
def render_cell(row, value, column, table, database, datasette, request):
|
||||
def render_cell(row, value, column, table, pks, database, datasette, request):
|
||||
async def inner():
|
||||
# Render some debug output in cell with value RENDER_CELL_DEMO
|
||||
if value == "RENDER_CELL_DEMO":
|
||||
|
|
@ -113,6 +113,7 @@ def render_cell(row, value, column, table, database, datasette, request):
|
|||
"column": column,
|
||||
"table": table,
|
||||
"database": database,
|
||||
"pks": pks,
|
||||
"config": datasette.plugin_config(
|
||||
"name-of-plugin",
|
||||
database=database,
|
||||
|
|
|
|||
|
|
@ -204,11 +204,57 @@ async def test_hook_render_cell_demo(ds_client):
|
|||
"column": "content",
|
||||
"table": "simple_primary_key",
|
||||
"database": "fixtures",
|
||||
"pks": ["id"],
|
||||
"config": {"depth": "table", "special": "this-is-simple_primary_key"},
|
||||
"render_cell_extra": 1,
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_hook_render_cell_pks_single_pk(ds_client):
|
||||
"""pks should be ["id"] for a table with a single primary key"""
|
||||
response = await ds_client.get("/fixtures/simple_primary_key?id=4")
|
||||
soup = Soup(response.text, "html.parser")
|
||||
td = soup.find("td", {"class": "col-content"})
|
||||
data = json.loads(td.string)
|
||||
assert data["pks"] == ["id"]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_hook_render_cell_pks_compound_pk(ds_client):
|
||||
"""pks should list all primary key columns for a compound pk table"""
|
||||
response = await ds_client.get("/fixtures/compound_primary_key?pk1=d&pk2=e")
|
||||
soup = Soup(response.text, "html.parser")
|
||||
td = soup.find("td", {"class": "col-content"})
|
||||
data = json.loads(td.string)
|
||||
assert data["pks"] == ["pk1", "pk2"]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_hook_render_cell_pks_rowid_table(ds_client):
|
||||
"""pks should be ["rowid"] for a table with no explicit primary key"""
|
||||
response = await ds_client.get(
|
||||
"/fixtures/no_primary_key?content=RENDER_CELL_DEMO"
|
||||
)
|
||||
soup = Soup(response.text, "html.parser")
|
||||
td = soup.find("td", {"class": "col-content"})
|
||||
data = json.loads(td.string)
|
||||
assert data["pks"] == ["rowid"]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_hook_render_cell_pks_custom_sql(ds_client):
|
||||
"""pks should be [] for custom SQL queries"""
|
||||
response = await ds_client.get(
|
||||
"/fixtures/-/query?sql=select+'RENDER_CELL_DEMO'+as+content"
|
||||
)
|
||||
soup = Soup(response.text, "html.parser")
|
||||
td = soup.find("td", {"class": "col-content"})
|
||||
data = json.loads(td.string)
|
||||
assert data["pks"] == []
|
||||
assert data["table"] is None
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize(
|
||||
"path",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue