Remove legacy .jsono format extension

The homepage routes now only accept .json, and the row view no longer
redirects .jsono to .json?_shape=objects. The .jsono extension was
superseded by ?_shape= and returned output identical to .json.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GrHZSypDfMnym1tM5XJAFZ
This commit is contained in:
Claude 2026-07-04 05:10:26 +00:00
commit bc51c00724
No known key found for this signature in database
4 changed files with 8 additions and 21 deletions

View file

@ -2514,8 +2514,8 @@ class Datasette:
def add_route(view, regex):
routes.append((regex, view))
add_route(IndexView.as_view(self), r"/(\.(?P<format>jsono?))?$")
add_route(IndexView.as_view(self), r"/-/(\.(?P<format>jsono?))?$")
add_route(IndexView.as_view(self), r"/(\.(?P<format>json))?$")
add_route(IndexView.as_view(self), r"/-/(\.(?P<format>json))?$")
add_route(permanent_redirect("/-/"), r"/-$")
add_route(favicon, "/favicon.ico")

View file

@ -21,7 +21,6 @@ from datasette.utils import (
InvalidSql,
make_slot_function,
path_from_row_pks,
path_with_added_args,
path_with_format,
path_with_removed_args,
to_css_class,
@ -209,18 +208,6 @@ class RowView(BaseView):
end = time.perf_counter()
data["query_ms"] = (end - start) * 1000
# Special case for .jsono extension - redirect to _shape=objects
if format_ == "jsono":
return self.redirect(
request,
path_with_added_args(
request,
{"_shape": "objects"},
path=request.path.rsplit(".jsono", 1)[0] + ".json",
),
forward_querystring=False,
)
if format_ in self.ds.renderers.keys():
# Dispatch request to the correct output format renderer
# (CSV is not handled here due to streaming)

View file

@ -25,8 +25,7 @@ directory: every claim below is based on the route table in `datasette/app.py`
- Most read endpoints are registered with an optional format suffix:
`/(...)(\.(?P<format>json))?$`. The bare path returns HTML; the `.json`
extension returns JSON. The homepage additionally accepts the legacy
`.jsono` extension, which returns identical JSON (app.py:2517-2518).
extension returns JSON.
- Table, row and query routes accept any `\w+` format extension; formats other
than the built-in `html`, `json`, `csv`, `blob` must be provided by a plugin
via `register_output_renderer`, otherwise the request 404s.
@ -772,8 +771,7 @@ tilde-encoded primary key values (rowid for rowid tables).
- **Foreign-key label expansion does not apply to row JSON**`_labels` has
no effect here; expansion happens only in the HTML path
(views/row.py:445-475).
- `_shape`, `_json`, `_nl`, `_json_infinity`, `_ttl` apply. A `.jsono`
request redirects to `.json?_shape=objects`.
- `_shape`, `_json`, `_nl`, `_json_infinity`, `_ttl` apply.
### The .blob format

View file

@ -233,8 +233,10 @@ Concerns:
`_labels=on/off`, `?all=1`, `is_write=1|0|true|false|t|f|yes|no|on|off`,
`_nocount=1`. Adopt one accepted set (the query-list parser at
query_helpers.py:81-94 is a good candidate) and apply it everywhere.
- **`.jsono`** survives on the homepage route (identical output to `.json`)
and as a row-view redirect. Remove it at 1.0; it is pure legacy.
- ~~**`.jsono`** survives on the homepage route (identical output to `.json`)
and as a row-view redirect. Remove it at 1.0; it is pure legacy.~~
✅ Removed: the homepage routes only accept `.json` and the row-view
redirect is gone.
- **`_json` is overloaded:** on GET it is a renderer option naming a column
to parse as JSON (repeatable); on canned-query POST a `_json` body field
forces a JSON response. Two unrelated meanings for one name.