\",\r\n```\r\nI'm going to add a `repr()` to it such that it's a bit more useful.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1058790545, "label": "base_url is omitted in JSON and CSV views"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1519#issuecomment-974420619", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1519", "id": 974420619, "node_id": "IC_kwDOBm6k_c46FHqL", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-11-19T20:25:19Z", "updated_at": "2021-11-19T20:25:19Z", "author_association": "OWNER", "body": "The implementations of `path_with_removed_args` and `path_with_format`:\r\n\r\nhttps://github.com/simonw/datasette/blob/85849935292e500ab7a99f8fe0f9546e903baad3/datasette/utils/__init__.py#L228-L254\r\n\r\nhttps://github.com/simonw/datasette/blob/85849935292e500ab7a99f8fe0f9546e903baad3/datasette/utils/__init__.py#L710-L729", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1058790545, "label": "base_url is omitted in JSON and CSV views"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1519#issuecomment-974418496", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1519", "id": 974418496, "node_id": "IC_kwDOBm6k_c46FHJA", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-11-19T20:24:16Z", "updated_at": "2021-11-19T20:24:16Z", "author_association": "OWNER", "body": "Here's the code that generates `edit_sql_url` correctly: https://github.com/simonw/datasette/blob/85849935292e500ab7a99f8fe0f9546e903baad3/datasette/views/database.py#L416-L420\r\n\r\nAnd here's the code for `show_hide_link`: https://github.com/simonw/datasette/blob/85849935292e500ab7a99f8fe0f9546e903baad3/datasette/views/database.py#L432-L433\r\n\r\nAnd for `url_csv`: https://github.com/simonw/datasette/blob/85849935292e500ab7a99f8fe0f9546e903baad3/datasette/views/base.py#L600-L602", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1058790545, "label": "base_url is omitted in JSON and CSV views"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1519#issuecomment-974405016", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1519", "id": 974405016, "node_id": "IC_kwDOBm6k_c46FD2Y", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-11-19T20:14:19Z", "updated_at": "2021-11-19T20:15:05Z", "author_association": "OWNER", "body": "I added `template_debug` in the Dockerfile:\r\n```\r\ndatasette fixtures.db --setting template_debug 1 --setting base_url \"/foo/bar/\" -p 9000 &\\n\\\r\n```\r\nAnd then hit `http://localhost:5000/foo/bar/fixtures?sql=select+*+from+compound_three_primary_keys+limit+1&_context=1` to view the template context - and it showed the bug, output edited to just show relevant keys:\r\n\r\n```json\r\n{\r\n \"edit_sql_url\": \"/foo/bar/fixtures?sql=select+%2A+from+compound_three_primary_keys+limit+1\",\r\n \"settings\": {\r\n \"force_https_urls\": false,\r\n \"template_debug\": true,\r\n \"trace_debug\": false,\r\n \"base_url\": \"/foo/bar/\"\r\n },\r\n \"show_hide_link\": \"/fixtures?sql=select+%2A+from+compound_three_primary_keys+limit+1&_context=1&_hide_sql=1\",\r\n \"show_hide_text\": \"hide\",\r\n \"show_hide_hidden\": \"\",\r\n \"renderers\": {\r\n \"json\": \"/fixtures.json?sql=select+*+from+compound_three_primary_keys+limit+1&_context=1\"\r\n },\r\n \"url_csv\": \"/fixtures.csv?sql=select+*+from+compound_three_primary_keys+limit+1&_context=1&_size=max\",\r\n \"url_csv_path\": \"/fixtures.csv\",\r\n \"base_url\": \"/foo/bar/\"\r\n}\r\n```\r\nThis is so strange. `edit_sql_url` and `base_url` are correct, but `show_hide_link` and `url_csv` and `renderers.json` are not.\r\n\r\nAnd it's _really strange_ that the bug doesn't show up in the tests.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1058790545, "label": "base_url is omitted in JSON and CSV views"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1519#issuecomment-974398399", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1519", "id": 974398399, "node_id": "IC_kwDOBm6k_c46FCO_", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-11-19T20:08:20Z", "updated_at": "2021-11-19T20:22:02Z", "author_association": "OWNER", "body": "The relevant test is this one: https://github.com/simonw/datasette/blob/30255055150d7bc0affc8156adc18295495020ff/tests/test_html.py#L1608-L1649\r\n\r\nI modified that test to add `\"/fixtures/facetable?sql=select+1\"` as one of the tested paths, and dropped in an `assert False` to pause it in the debugger:\r\n```\r\n @pytest.mark.parametrize(\r\n \"path\",\r\n [\r\n \"/\",\r\n \"/fixtures\",\r\n \"/fixtures/compound_three_primary_keys\",\r\n \"/fixtures/compound_three_primary_keys/a,a,a\",\r\n \"/fixtures/paginated_view\",\r\n \"/fixtures/facetable\",\r\n \"/fixtures?sql=select+1\",\r\n ],\r\n )\r\n def test_base_url_config(app_client_base_url_prefix, path):\r\n client = app_client_base_url_prefix\r\n response = client.get(\"/prefix/\" + path.lstrip(\"/\"))\r\n soup = Soup(response.body, \"html.parser\")\r\n if path == \"/fixtures?sql=select+1\":\r\n> assert False\r\nE assert False\r\n```\r\nBUT... in the debugger:\r\n```\r\n(Pdb) print(soup)\r\n...\r\nThis data as\r\n json,\r\n testall,\r\n testnone,\r\n testresponse,\r\n CSV
\r\n```\r\nThose all have the correct prefix! But that's not what I'm seeing in my `Dockerfile` reproduction of the issue.\r\n\r\nSomething very weird is going on here.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1058790545, "label": "base_url is omitted in JSON and CSV views"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1519#issuecomment-974391204", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1519", "id": 974391204, "node_id": "IC_kwDOBm6k_c46FAek", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-11-19T20:02:41Z", "updated_at": "2021-11-19T20:02:41Z", "author_association": "OWNER", "body": "Bug confirmed:\r\n\r\n![proxy-bug](https://user-images.githubusercontent.com/9599/142684666-112136bf-9243-4b6e-8202-339fcfe91bcc.gif)\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1058790545, "label": "base_url is omitted in JSON and CSV views"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1519#issuecomment-974389472", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1519", "id": 974389472, "node_id": "IC_kwDOBm6k_c46FADg", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-11-19T20:01:02Z", "updated_at": "2021-11-19T20:01:02Z", "author_association": "OWNER", "body": "I now have a `Dockerfile` in https://github.com/simonw/datasette/issues/1521#issuecomment-974388295 that I can use to run a local Apache 2 with `mod_proxy` to investigate this class of bugs!", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1058790545, "label": "base_url is omitted in JSON and CSV views"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1519#issuecomment-974310208", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1519", "id": 974310208, "node_id": "IC_kwDOBm6k_c46EstA", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-11-19T18:32:31Z", "updated_at": "2021-11-19T18:32:31Z", "author_association": "OWNER", "body": "Having a live demo running on Cloud Run that proxies through Apache and uses `base_url` would be incredibly useful for replicating and debugging this kind of thing. I wonder how hard it is to run Apache and `mod_proxy` in the same Docker container as Datasette?", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1058790545, "label": "base_url is omitted in JSON and CSV views"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1519#issuecomment-974309591", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1519", "id": 974309591, "node_id": "IC_kwDOBm6k_c46EsjX", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-11-19T18:31:32Z", "updated_at": "2021-11-19T18:31:32Z", "author_association": "OWNER", "body": "`base_url` has been a source of so many bugs like this! I often find them quite hard to replicate, likely because I haven't made myself a good Apache `mod_proxy` testing environment yet.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1058790545, "label": "base_url is omitted in JSON and CSV views"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1518#issuecomment-974300823", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1518", "id": 974300823, "node_id": "IC_kwDOBm6k_c46EqaX", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-11-19T18:18:32Z", "updated_at": "2021-11-19T18:18:32Z", "author_association": "OWNER", "body": "> This may be an argument for continuing to allow non-JSON-objects through to the HTML templates. Need to think about that a bit more.\r\n\r\nI can definitely support this using pure-JSON - I could make two versions of the row available, one that's an array of cell objects and the other that's an object mapping column names to column raw values.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1058072543, "label": "Complete refactor of TableView and table.html template"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1518#issuecomment-974287570", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1518", "id": 974287570, "node_id": "IC_kwDOBm6k_c46EnLS", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-11-19T17:59:33Z", "updated_at": "2021-11-19T17:59:33Z", "author_association": "OWNER", "body": "I'm going to try leaning into the `asyncinject` mechanism a bit here. One method can execute and return the raw rows. Another can turn that into the default minimal JSON representation. Then a third can take that (or take both) and use it to inflate out the JSON that the HTML template needs, with those extras and with the rendered cells from plugins.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1058072543, "label": "Complete refactor of TableView and table.html template"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1518#issuecomment-974285803", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1518", "id": 974285803, "node_id": "IC_kwDOBm6k_c46Emvr", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-11-19T17:56:48Z", "updated_at": "2021-11-19T18:14:30Z", "author_association": "OWNER", "body": "Very confused by this piece of code here: https://github.com/simonw/datasette/blob/1c13e1af0664a4dfb1e69714c56523279cae09e4/datasette/views/table.py#L37-L63\r\n\r\nI added it in https://github.com/simonw/datasette/commit/754836eef043676e84626c4fd3cb993eed0d2976 - in the new world that should probably be replaced by pure JSON.\r\n\r\nAha - this comment explains it: https://github.com/simonw/datasette/issues/521#issuecomment-505279560\r\n\r\n> I think the trick is to redefine what a \"cell_row\" is. Each row is currently a list of cells:\r\n> \r\n> https://github.com/simonw/datasette/blob/6341f8cbc7833022012804dea120b838ec1f6558/datasette/views/table.py#L159-L163\r\n> \r\n> I can redefine the row (the `cells` variable in the above example) as a thing-that-iterates-cells (hence behaving like a list) but that also supports `__getitem__` access for looking up cell values if you know the name of the column.\r\n\r\nThe goal was to support neater custom templates like this:\r\n```html+jinja\r\n{% for row in display_rows %}\r\n {{ row[\"First_Name\"] }} {{ row[\"Last_Name\"] }}
\r\n ...\r\n```\r\nThis may be an argument for continuing to allow non-JSON-objects through to the HTML templates. Need to think about that a bit more.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1058072543, "label": "Complete refactor of TableView and table.html template"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1518#issuecomment-973700549", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1518", "id": 973700549, "node_id": "IC_kwDOBm6k_c46CX3F", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-11-19T03:31:20Z", "updated_at": "2021-11-19T03:31:26Z", "author_association": "OWNER", "body": "... and while I'm doing all of this I can rewrite the templates to not use those cheating magical functions AND document the template context at the same time, refs:\r\n- #1510.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1058072543, "label": "Complete refactor of TableView and table.html template"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1518#issuecomment-973700322", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1518", "id": 973700322, "node_id": "IC_kwDOBm6k_c46CXzi", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-11-19T03:30:30Z", "updated_at": "2021-11-19T03:30:30Z", "author_association": "OWNER", "body": "Right now the HTML version gets to cheat - it passes through objects that are not JSON serializable, including custom functions that can then be called by Jinja.\r\n\r\nI'm interested in maybe removing this cheating - if the HTML version could only request JSON-serializable extras those could be exposed in the API as well.\r\n\r\nIt would also help cleanup the kind-of-nasty pattern I use in the current `BaseView` where everything returns both a bunch of JSON-serializable data AND an awaitable function that then gets to add extra things to the HTML context.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1058072543, "label": "Complete refactor of TableView and table.html template"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1518#issuecomment-973699424", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1518", "id": 973699424, "node_id": "IC_kwDOBm6k_c46CXlg", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-11-19T03:27:49Z", "updated_at": "2021-11-19T03:27:49Z", "author_association": "OWNER", "body": "My goal is to break up a lot of this functionality into separate methods. These methods can be executed in parallel by `asyncinject`, but more importantly they can be used to build a much better JSON representation, where the default representation is lighter and `?_extra=x` options can be used to execute more expensive portions and add them to the response.\r\n\r\nSo the HTML version itself needs to be re-written to use those JSON extras.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1058072543, "label": "Complete refactor of TableView and table.html template"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1518#issuecomment-973698917", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1518", "id": 973698917, "node_id": "IC_kwDOBm6k_c46CXdl", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-11-19T03:26:18Z", "updated_at": "2021-11-19T03:29:03Z", "author_association": "OWNER", "body": "A (likely incomplete) list of features on the table page:\r\n\r\n- [ ] Display table/database/instance metadata\r\n- [ ] Show count of all results\r\n- [ ] Display table of results\r\n - [ ] Special table display treatment for URLs, numbers\r\n - [ ] Allow plugins to modify table cells\r\n - [ ] Respect `?_col=` and `?_nocol=`\r\n- [ ] Show interface for filtering by columns and operations\r\n- [ ] Show search box, support executing FTS searches\r\n- [ ] Sort table by specified column\r\n- [ ] Paginate table\r\n- [ ] Show facet results\r\n- [ ] Show suggested facets\r\n- [ ] Link to available exports\r\n- [ ] Display schema for table\r\n - [ ] Maybe it should show the SQL for the query too?\r\n- [ ] Handle various non-obvious querystring options, like `?_where=` and `?_through=`", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1058072543, "label": "Complete refactor of TableView and table.html template"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1518#issuecomment-973687978", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1518", "id": 973687978, "node_id": "IC_kwDOBm6k_c46CUyq", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-11-19T03:07:47Z", "updated_at": "2021-11-19T03:07:47Z", "author_association": "OWNER", "body": "I was wrong about that, you CAN over-ride default routes already.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1058072543, "label": "Complete refactor of TableView and table.html template"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1518#issuecomment-973682389", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1518", "id": 973682389, "node_id": "IC_kwDOBm6k_c46CTbV", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-11-19T02:57:39Z", "updated_at": "2021-11-19T02:57:39Z", "author_association": "OWNER", "body": "Ideally I'd like to execute the existing test suite against the new implementation - that would require me to solve this so I can replace the view with the plugin version though:\r\n\r\n- #1517 ", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1058072543, "label": "Complete refactor of TableView and table.html template"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1518#issuecomment-973681970", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1518", "id": 973681970, "node_id": "IC_kwDOBm6k_c46CTUy", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-11-19T02:56:31Z", "updated_at": "2021-11-19T02:56:53Z", "author_association": "OWNER", "body": "Here's where I got to with my hacked-together initial plugin prototype - it managed to render the table page with some rows on it (and a bunch of missing functionality such as filters): https://gist.github.com/simonw/281eac9c73b062c3469607ad86470eb2\r\n\r\n\r\n\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1058072543, "label": "Complete refactor of TableView and table.html template"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1517#issuecomment-973696604", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1517", "id": 973696604, "node_id": "IC_kwDOBm6k_c46CW5c", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-11-19T03:20:00Z", "updated_at": "2021-11-19T03:20:00Z", "author_association": "OWNER", "body": "Confirmed - my test plugin is indeed correctly over-riding the table page.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1057996111, "label": "Let `register_routes()` over-ride default routes within Datasette"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1517#issuecomment-973686874", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1517", "id": 973686874, "node_id": "IC_kwDOBm6k_c46CUha", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-11-19T03:06:58Z", "updated_at": "2021-11-19T03:06:58Z", "author_association": "OWNER", "body": "I made a mistake: I just wrote a test that proves that plugins CAN over-ride default routes, plus if you look at the code here the plugins get to register themselves first: https://github.com/simonw/datasette/blob/0156c6b5e52d541e93f0d68e9245f20ae83bc933/datasette/app.py#L965-L981", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1057996111, "label": "Let `register_routes()` over-ride default routes within Datasette"}, "performed_via_github_app": null}