path and full_path arguments for output renderers, closes #1179

Output renderer render() and can_render() callbacks can now accept
path and full_path arguments - the path to the HTML version of the
page without the .extension, with and without the query string.

Also fixed path_with_format() so it replaces the extension the current
request used instead of falling back to ?_format=, which Datasette no
longer reads. This broke links generated by renderers such as
datasette-export-notebook, and the URLs returned by ?_extra=renderers
on .json pages.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TzcVp1Cq5yCRW81GiN88JX
This commit is contained in:
Claude 2026-10-05 21:44:50 +00:00
commit cf6357cf93
No known key found for this signature in database
10 changed files with 180 additions and 7 deletions

View file

@ -578,6 +578,56 @@ def test_path_with_format_can_override_request_path():
assert "/foo.json?x=1" == actual
@pytest.mark.parametrize(
"path,url_vars,expected",
[
# https://github.com/simonw/datasette/issues/1179
("/db/table.Notebook", {"format": "Notebook"}, "/db/table.json"),
("/db/table.csv?_size=max", {"format": "csv"}, "/db/table.json?_size=max"),
("/db/table", {}, "/db/table.json"),
],
)
def test_path_with_format_replaces_current_format(path, url_vars, expected):
request = Request.fake(path, url_vars=url_vars)
assert utils.path_with_format(request=request, format="json") == expected
def test_path_with_format_replaces_current_format_with_path_override():
request = Request.fake("/prefix/db/table.csv?x=1", url_vars={"format": "csv"})
actual = utils.path_with_format(
request=request, path="/db/table.csv", format="json"
)
assert actual == "/db/table.json?x=1"
@pytest.mark.parametrize(
"path,url_vars,expected_path,expected_full_path",
[
("/db/table", {}, "/db/table", "/db/table"),
("/db/table.json", {"format": "json"}, "/db/table", "/db/table"),
(
"/db/table.Notebook?_sort=pk",
{"format": "Notebook"},
"/db/table",
"/db/table?_sort=pk",
),
(
"/prefix/db/-/query.csv?sql=select+1",
{"format": "csv"},
"/prefix/db/-/query",
"/prefix/db/-/query?sql=select+1",
),
],
)
def test_path_without_format(path, url_vars, expected_path, expected_full_path):
request = Request.fake(path, url_vars=url_vars)
assert utils.path_without_format(request) == expected_path
assert (
utils.path_without_format(request, include_query_string=True)
== expected_full_path
)
@pytest.mark.parametrize(
"bytes,expected",
[