mirror of
https://github.com/simonw/datasette.git
synced 2025-12-10 16:51:24 +01:00
Make request available to menu plugin hooks, closes #1371
This commit is contained in:
parent
a3faf37883
commit
d23a267138
8 changed files with 44 additions and 23 deletions
|
|
@ -833,7 +833,9 @@ class Datasette:
|
||||||
async def menu_links():
|
async def menu_links():
|
||||||
links = []
|
links = []
|
||||||
for hook in pm.hook.menu_links(
|
for hook in pm.hook.menu_links(
|
||||||
datasette=self, actor=request.actor if request else None
|
datasette=self,
|
||||||
|
actor=request.actor if request else None,
|
||||||
|
request=request or None,
|
||||||
):
|
):
|
||||||
extra_links = await await_me_maybe(hook)
|
extra_links = await await_me_maybe(hook)
|
||||||
if extra_links:
|
if extra_links:
|
||||||
|
|
|
||||||
|
|
@ -100,15 +100,15 @@ def forbidden(datasette, request, message):
|
||||||
|
|
||||||
|
|
||||||
@hookspec
|
@hookspec
|
||||||
def menu_links(datasette, actor):
|
def menu_links(datasette, actor, request):
|
||||||
"""Links for the navigation menu"""
|
"""Links for the navigation menu"""
|
||||||
|
|
||||||
|
|
||||||
@hookspec
|
@hookspec
|
||||||
def table_actions(datasette, actor, database, table):
|
def table_actions(datasette, actor, database, table, request):
|
||||||
"""Links for the table actions menu"""
|
"""Links for the table actions menu"""
|
||||||
|
|
||||||
|
|
||||||
@hookspec
|
@hookspec
|
||||||
def database_actions(datasette, actor, database):
|
def database_actions(datasette, actor, database, request):
|
||||||
"""Links for the database actions menu"""
|
"""Links for the database actions menu"""
|
||||||
|
|
|
||||||
|
|
@ -110,6 +110,7 @@ class DatabaseView(DataView):
|
||||||
datasette=self.ds,
|
datasette=self.ds,
|
||||||
database=database,
|
database=database,
|
||||||
actor=request.actor,
|
actor=request.actor,
|
||||||
|
request=request,
|
||||||
):
|
):
|
||||||
extra_links = await await_me_maybe(hook)
|
extra_links = await await_me_maybe(hook)
|
||||||
if extra_links:
|
if extra_links:
|
||||||
|
|
|
||||||
|
|
@ -894,6 +894,7 @@ class TableView(RowTableShared):
|
||||||
table=table,
|
table=table,
|
||||||
database=database,
|
database=database,
|
||||||
actor=request.actor,
|
actor=request.actor,
|
||||||
|
request=request,
|
||||||
):
|
):
|
||||||
extra_links = await await_me_maybe(hook)
|
extra_links = await await_me_maybe(hook)
|
||||||
if extra_links:
|
if extra_links:
|
||||||
|
|
|
||||||
|
|
@ -1015,8 +1015,8 @@ The function can alternatively return an awaitable function if it needs to make
|
||||||
|
|
||||||
.. _plugin_hook_menu_links:
|
.. _plugin_hook_menu_links:
|
||||||
|
|
||||||
menu_links(datasette, actor)
|
menu_links(datasette, actor, request)
|
||||||
----------------------------
|
-------------------------------------
|
||||||
|
|
||||||
``datasette`` - :ref:`internals_datasette`
|
``datasette`` - :ref:`internals_datasette`
|
||||||
You can use this to access plugin configuration options via ``datasette.plugin_config(your_plugin_name)``, or to execute SQL queries.
|
You can use this to access plugin configuration options via ``datasette.plugin_config(your_plugin_name)``, or to execute SQL queries.
|
||||||
|
|
@ -1024,6 +1024,9 @@ menu_links(datasette, actor)
|
||||||
``actor`` - dictionary or None
|
``actor`` - dictionary or None
|
||||||
The currently authenticated :ref:`actor <authentication_actor>`.
|
The currently authenticated :ref:`actor <authentication_actor>`.
|
||||||
|
|
||||||
|
``request`` - object or None
|
||||||
|
The current HTTP :ref:`internals_request`. This can be ``None`` if the request object is not available.
|
||||||
|
|
||||||
This hook allows additional items to be included in the menu displayed by Datasette's top right menu icon.
|
This hook allows additional items to be included in the menu displayed by Datasette's top right menu icon.
|
||||||
|
|
||||||
The hook should return a list of ``{"href": "...", "label": "..."}`` menu items. These will be added to the menu.
|
The hook should return a list of ``{"href": "...", "label": "..."}`` menu items. These will be added to the menu.
|
||||||
|
|
@ -1045,11 +1048,10 @@ This example adds a new menu item but only if the signed in user is ``"root"``:
|
||||||
|
|
||||||
Using :ref:`internals_datasette_urls` here ensures that links in the menu will take the :ref:`setting_base_url` setting into account.
|
Using :ref:`internals_datasette_urls` here ensures that links in the menu will take the :ref:`setting_base_url` setting into account.
|
||||||
|
|
||||||
|
|
||||||
.. _plugin_hook_table_actions:
|
.. _plugin_hook_table_actions:
|
||||||
|
|
||||||
table_actions(datasette, actor, database, table)
|
table_actions(datasette, actor, database, table, request)
|
||||||
------------------------------------------------
|
---------------------------------------------------------
|
||||||
|
|
||||||
``datasette`` - :ref:`internals_datasette`
|
``datasette`` - :ref:`internals_datasette`
|
||||||
You can use this to access plugin configuration options via ``datasette.plugin_config(your_plugin_name)``, or to execute SQL queries.
|
You can use this to access plugin configuration options via ``datasette.plugin_config(your_plugin_name)``, or to execute SQL queries.
|
||||||
|
|
@ -1063,6 +1065,9 @@ table_actions(datasette, actor, database, table)
|
||||||
``table`` - string
|
``table`` - string
|
||||||
The name of the table.
|
The name of the table.
|
||||||
|
|
||||||
|
``request`` - object
|
||||||
|
The current HTTP :ref:`internals_request`. This can be ``None`` if the request object is not available.
|
||||||
|
|
||||||
This hook allows table actions to be displayed in a menu accessed via an action icon at the top of the table page. It should return a list of ``{"href": "...", "label": "..."}`` menu items.
|
This hook allows table actions to be displayed in a menu accessed via an action icon at the top of the table page. It should return a list of ``{"href": "...", "label": "..."}`` menu items.
|
||||||
|
|
||||||
It can alternatively return an ``async def`` awaitable function which returns a list of menu items.
|
It can alternatively return an ``async def`` awaitable function which returns a list of menu items.
|
||||||
|
|
@ -1083,8 +1088,8 @@ This example adds a new table action if the signed in user is ``"root"``:
|
||||||
|
|
||||||
.. _plugin_hook_database_actions:
|
.. _plugin_hook_database_actions:
|
||||||
|
|
||||||
database_actions(datasette, actor, database)
|
database_actions(datasette, actor, database, request)
|
||||||
--------------------------------------------
|
-----------------------------------------------------
|
||||||
|
|
||||||
``datasette`` - :ref:`internals_datasette`
|
``datasette`` - :ref:`internals_datasette`
|
||||||
You can use this to access plugin configuration options via ``datasette.plugin_config(your_plugin_name)``, or to execute SQL queries.
|
You can use this to access plugin configuration options via ``datasette.plugin_config(your_plugin_name)``, or to execute SQL queries.
|
||||||
|
|
@ -1095,4 +1100,7 @@ database_actions(datasette, actor, database)
|
||||||
``database`` - string
|
``database`` - string
|
||||||
The name of the database.
|
The name of the database.
|
||||||
|
|
||||||
|
``request`` - object
|
||||||
|
The current HTTP :ref:`internals_request`.
|
||||||
|
|
||||||
This hook is similar to :ref:`plugin_hook_table_actions` but populates an actions menu on the database page.
|
This hook is similar to :ref:`plugin_hook_table_actions` but populates an actions menu on the database page.
|
||||||
|
|
|
||||||
|
|
@ -316,9 +316,12 @@ def forbidden(datasette, request, message):
|
||||||
|
|
||||||
|
|
||||||
@hookimpl
|
@hookimpl
|
||||||
def menu_links(datasette, actor):
|
def menu_links(datasette, actor, request):
|
||||||
if actor:
|
if actor:
|
||||||
return [{"href": datasette.urls.instance(), "label": "Hello"}]
|
label = "Hello"
|
||||||
|
if request.args.get("_hello"):
|
||||||
|
label += ", " + request.args["_hello"]
|
||||||
|
return [{"href": datasette.urls.instance(), "label": label}]
|
||||||
|
|
||||||
|
|
||||||
@hookimpl
|
@hookimpl
|
||||||
|
|
@ -334,11 +337,14 @@ def table_actions(datasette, database, table, actor):
|
||||||
|
|
||||||
|
|
||||||
@hookimpl
|
@hookimpl
|
||||||
def database_actions(datasette, database, actor):
|
def database_actions(datasette, database, actor, request):
|
||||||
if actor:
|
if actor:
|
||||||
|
label = f"Database: {database}"
|
||||||
|
if request.args.get("_hello"):
|
||||||
|
label += " - " + request.args["_hello"]
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
"href": datasette.urls.instance(),
|
"href": datasette.urls.instance(),
|
||||||
"label": f"Database: {database}",
|
"label": label,
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -158,9 +158,12 @@ def menu_links(datasette, actor):
|
||||||
|
|
||||||
|
|
||||||
@hookimpl
|
@hookimpl
|
||||||
def table_actions(datasette, database, table, actor):
|
def table_actions(datasette, database, table, actor, request):
|
||||||
async def inner():
|
async def inner():
|
||||||
if actor:
|
if actor:
|
||||||
return [{"href": datasette.urls.instance(), "label": "From async"}]
|
label = "From async"
|
||||||
|
if request.args.get("_hello"):
|
||||||
|
label += " " + request.args["_hello"]
|
||||||
|
return [{"href": datasette.urls.instance(), "label": label}]
|
||||||
|
|
||||||
return inner
|
return inner
|
||||||
|
|
|
||||||
|
|
@ -781,9 +781,9 @@ def test_hook_menu_links(app_client):
|
||||||
response = app_client.get("/")
|
response = app_client.get("/")
|
||||||
assert get_menu_links(response.text) == []
|
assert get_menu_links(response.text) == []
|
||||||
|
|
||||||
response_2 = app_client.get("/?_bot=1")
|
response_2 = app_client.get("/?_bot=1&_hello=BOB")
|
||||||
assert get_menu_links(response_2.text) == [
|
assert get_menu_links(response_2.text) == [
|
||||||
{"label": "Hello", "href": "/"},
|
{"label": "Hello, BOB", "href": "/"},
|
||||||
{"label": "Hello 2", "href": "/"},
|
{"label": "Hello 2", "href": "/"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -800,12 +800,12 @@ def test_hook_table_actions(app_client, table_or_view):
|
||||||
response = app_client.get(f"/fixtures/{table_or_view}")
|
response = app_client.get(f"/fixtures/{table_or_view}")
|
||||||
assert get_table_actions_links(response.text) == []
|
assert get_table_actions_links(response.text) == []
|
||||||
|
|
||||||
response_2 = app_client.get(f"/fixtures/{table_or_view}?_bot=1")
|
response_2 = app_client.get(f"/fixtures/{table_or_view}?_bot=1&_hello=BOB")
|
||||||
assert sorted(
|
assert sorted(
|
||||||
get_table_actions_links(response_2.text), key=lambda l: l["label"]
|
get_table_actions_links(response_2.text), key=lambda l: l["label"]
|
||||||
) == [
|
) == [
|
||||||
{"label": "Database: fixtures", "href": "/"},
|
{"label": "Database: fixtures", "href": "/"},
|
||||||
{"label": "From async", "href": "/"},
|
{"label": "From async BOB", "href": "/"},
|
||||||
{"label": f"Table: {table_or_view}", "href": "/"},
|
{"label": f"Table: {table_or_view}", "href": "/"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -821,7 +821,7 @@ def test_hook_database_actions(app_client):
|
||||||
response = app_client.get("/fixtures")
|
response = app_client.get("/fixtures")
|
||||||
assert get_table_actions_links(response.text) == []
|
assert get_table_actions_links(response.text) == []
|
||||||
|
|
||||||
response_2 = app_client.get("/fixtures?_bot=1")
|
response_2 = app_client.get("/fixtures?_bot=1&_hello=BOB")
|
||||||
assert get_table_actions_links(response_2.text) == [
|
assert get_table_actions_links(response_2.text) == [
|
||||||
{"label": "Database: fixtures", "href": "/"},
|
{"label": "Database: fixtures - BOB", "href": "/"},
|
||||||
]
|
]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue