diff --git a/datasette/app.py b/datasette/app.py index 5f348cb5..2596ca50 100644 --- a/datasette/app.py +++ b/datasette/app.py @@ -960,7 +960,7 @@ class Datasette: """Returns an ASGI app function that serves the whole of Datasette""" routes = [] - for routes_to_add in pm.hook.register_routes(): + for routes_to_add in pm.hook.register_routes(datasette=self): for regex, view_fn in routes_to_add: routes.append((regex, wrap_view(view_fn, self))) diff --git a/datasette/hookspecs.py b/datasette/hookspecs.py index 07b2f5ba..3ef0d4f5 100644 --- a/datasette/hookspecs.py +++ b/datasette/hookspecs.py @@ -75,7 +75,7 @@ def register_facet_classes(): @hookspec -def register_routes(): +def register_routes(datasette): """Register URL routes: return a list of (regex, view_function) pairs""" diff --git a/docs/plugin_hooks.rst b/docs/plugin_hooks.rst index 63258e2f..4700763c 100644 --- a/docs/plugin_hooks.rst +++ b/docs/plugin_hooks.rst @@ -529,8 +529,11 @@ Examples: `datasette-atom `_, `dataset .. _plugin_register_routes: -register_routes() ------------------ +register_routes(datasette) +-------------------------- + +``datasette`` - :ref:`internals_datasette` + You can use this to access plugin configuration options via ``datasette.plugin_config(your_plugin_name)`` Register additional view functions to execute for specified URL routes. diff --git a/tests/fixtures.py b/tests/fixtures.py index dce94876..93b7dce2 100644 --- a/tests/fixtures.py +++ b/tests/fixtures.py @@ -70,6 +70,7 @@ EXPECTED_PLUGINS = [ "extra_template_vars", "menu_links", "permission_allowed", + "register_routes", "render_cell", "startup", "table_actions", diff --git a/tests/plugins/my_plugin_2.py b/tests/plugins/my_plugin_2.py index b70372f3..f7a3f1c0 100644 --- a/tests/plugins/my_plugin_2.py +++ b/tests/plugins/my_plugin_2.py @@ -1,4 +1,5 @@ from datasette import hookimpl +from datasette.utils.asgi import Response from functools import wraps import markupsafe import json @@ -167,3 +168,12 @@ def table_actions(datasette, database, table, actor, request): return [{"href": datasette.urls.instance(), "label": label}] return inner + + +@hookimpl +def register_routes(datasette): + config = datasette.plugin_config("register-route-demo") + if not config: + return + path = config["path"] + return [(r"/{}/$".format(path), lambda: Response.text(path.upper()))] diff --git a/tests/test_plugins.py b/tests/test_plugins.py index 7a626ce5..0c01b7ae 100644 --- a/tests/test_plugins.py +++ b/tests/test_plugins.py @@ -648,6 +648,25 @@ def test_hook_register_routes(app_client, path, body): assert body == response.text +@pytest.mark.parametrize("configured_path", ("path1", "path2")) +def test_hook_register_routes_with_datasette(configured_path): + with make_app_client( + metadata={ + "plugins": { + "register-route-demo": { + "path": configured_path, + } + } + } + ) as client: + response = client.get(f"/{configured_path}/") + assert response.status == 200 + assert configured_path.upper() == response.text + # Other one should 404 + other_path = [p for p in ("path1", "path2") if configured_path != p][0] + assert client.get(f"/{other_path}/").status == 404 + + def test_hook_register_routes_post(app_client): response = app_client.post("/post/", {"this is": "post data"}, csrftoken_from=True) assert 200 == response.status