{"ok": true, "next": null, "facet_results": {"results": {"breadcrumbs": {"name": "breadcrumbs", "type": "array", "results": [{"value": "0.29 (2019-07-07)", "label": "0.29 (2019-07-07)", "count": 8, "toggle_url": "https://latest-docs.datasette.io/docs/sections.json?_facet_array=breadcrumbs", "selected": true}, {"value": "Changelog", "label": "Changelog", "count": 8, "toggle_url": "https://latest-docs.datasette.io/docs/sections.json?_facet_array=breadcrumbs&breadcrumbs__arraycontains=0.29+%282019-07-07%29&breadcrumbs__arraycontains=Changelog", "selected": false}], "hideable": true, "toggle_url": "/docs/sections.json?breadcrumbs__arraycontains=0.29+%282019-07-07%29", "truncated": false}}, "timed_out": []}, "rows": [{"id": "changelog:asgi", "page": "changelog", "ref": "asgi", "title": "ASGI", "content": "ASGI  is the Asynchronous Server Gateway Interface standard. I've been wanting to convert Datasette into an ASGI application for over a year -  Port Datasette to ASGI #272  tracks thirteen months of intermittent development - but with Datasette 0.29 the change is finally released. This also means Datasette now runs on top of  Uvicorn  and no longer depends on  Sanic . \n                 I wrote about the significance of this change in  Porting Datasette to ASGI, and Turtles all the way down . \n                 The most exciting consequence of this change is that Datasette plugins can now take advantage of the ASGI standard.", "breadcrumbs": "[\"Changelog\", \"0.29 (2019-07-07)\"]", "references": "[{\"href\": \"https://asgi.readthedocs.io/\", \"label\": \"ASGI\"}, {\"href\": \"https://github.com/simonw/datasette/issues/272\", \"label\": \"Port Datasette to ASGI #272\"}, {\"href\": \"https://www.uvicorn.org/\", \"label\": \"Uvicorn\"}, {\"href\": \"https://github.com/huge-success/sanic\", \"label\": \"Sanic\"}, {\"href\": \"https://simonwillison.net/2019/Jun/23/datasette-asgi/\", \"label\": \"Porting Datasette to ASGI, and Turtles all the way down\"}]"}, {"id": "changelog:facet-by-date", "page": "changelog", "ref": "facet-by-date", "title": "Facet by date", "content": "If a column contains datetime values, Datasette can now facet that column by date. ( #481 )", "breadcrumbs": "[\"Changelog\", \"0.29 (2019-07-07)\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/481\", \"label\": \"#481\"}]"}, {"id": "changelog:new-plugin-hook-asgi-wrapper", "page": "changelog", "ref": "new-plugin-hook-asgi-wrapper", "title": "New plugin hook: asgi_wrapper", "content": "The  asgi_wrapper(datasette)  plugin hook allows plugins to entirely wrap the Datasette ASGI application in their own ASGI middleware. ( #520 ) \n                 Two new plugins take advantage of this hook: \n                 \n                     \n                         datasette-auth-github  adds a authentication layer: users will have to sign in using their GitHub account before they can view data or interact with Datasette. You can also use it to restrict access to specific GitHub users, or to members of specified GitHub  organizations  or  teams . \n                     \n                     \n                         datasette-cors  allows you to configure  CORS headers  for your Datasette instance. You can use this to enable JavaScript running on a whitelisted set of domains to make  fetch()  calls to the JSON API provided by your Datasette instance.", "breadcrumbs": "[\"Changelog\", \"0.29 (2019-07-07)\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/520\", \"label\": \"#520\"}, {\"href\": \"https://github.com/simonw/datasette-auth-github\", \"label\": \"datasette-auth-github\"}, {\"href\": \"https://help.github.com/en/articles/about-organizations\", \"label\": \"organizations\"}, {\"href\": \"https://help.github.com/en/articles/organizing-members-into-teams\", \"label\": \"teams\"}, {\"href\": \"https://github.com/simonw/datasette-cors\", \"label\": \"datasette-cors\"}, {\"href\": \"https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS\", \"label\": \"CORS headers\"}]"}, {"id": "changelog:new-plugin-hook-extra-template-vars", "page": "changelog", "ref": "new-plugin-hook-extra-template-vars", "title": "New plugin hook: extra_template_vars", "content": "The  extra_template_vars(template, database, table, columns, view_name, request, datasette)  plugin hook allows plugins to inject their own additional variables into the Datasette template context. This can be used in conjunction with custom templates to customize the Datasette interface.  datasette-auth-github  uses this hook to add custom HTML to the new top navigation bar (which is designed to be modified by plugins, see  #540 ).", "breadcrumbs": "[\"Changelog\", \"0.29 (2019-07-07)\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette-auth-github\", \"label\": \"datasette-auth-github\"}, {\"href\": \"https://github.com/simonw/datasette/issues/540\", \"label\": \"#540\"}]"}, {"id": "changelog:secret-plugin-configuration-options", "page": "changelog", "ref": "secret-plugin-configuration-options", "title": "Secret plugin configuration options", "content": "Plugins like  datasette-auth-github  need a safe way to set secret configuration options. Since the default mechanism for configuring plugins exposes those settings in  /-/metadata  a new mechanism was needed.  Secret configuration values  describes how plugins can now specify that their settings should be read from a file or an environment variable: \n                 {\n    \"plugins\": {\n        \"datasette-auth-github\": {\n            \"client_secret\": {\n                \"$env\": \"GITHUB_CLIENT_SECRET\"\n            }\n        }\n    }\n} \n                 These plugin secrets can be set directly using  datasette publish . See  Custom metadata and plugins  for details. ( #538  and  #543 )", "breadcrumbs": "[\"Changelog\", \"0.29 (2019-07-07)\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette-auth-github\", \"label\": \"datasette-auth-github\"}, {\"href\": \"https://github.com/simonw/datasette/issues/538\", \"label\": \"#538\"}, {\"href\": \"https://github.com/simonw/datasette/issues/543\", \"label\": \"#543\"}]"}, {"id": "changelog:small-changes", "page": "changelog", "ref": "small-changes", "title": "Small changes", "content": "Databases published using  datasette publish  now open in  Immutable mode . ( #469 ) \n                     \n                     \n                         ?col__date=  now works for columns containing spaces \n                     \n                     \n                         Automatic label detection (for deciding which column to show when linking to a foreign key) has been improved. ( #485 ) \n                     \n                     \n                         Fixed bug where pagination broke when combined with an expanded foreign key. ( #489 ) \n                     \n                     \n                         Contributors can now run  pip install -e .[docs]  to get all of the dependencies needed to build the documentation, including  cd docs && make livehtml  support. \n                     \n                     \n                         Datasette's dependencies are now all specified using the  ~=  match operator. ( #532 ) \n                     \n                     \n                         white-space: pre-wrap  now used for table creation SQL. ( #505 ) \n                     \n                 \n                 Full list of commits  between 0.28 and 0.29.", "breadcrumbs": "[\"Changelog\", \"0.29 (2019-07-07)\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/issues/469\", \"label\": \"#469\"}, {\"href\": \"https://github.com/simonw/datasette/issues/485\", \"label\": \"#485\"}, {\"href\": \"https://github.com/simonw/datasette/issues/489\", \"label\": \"#489\"}, {\"href\": \"https://github.com/simonw/datasette/issues/532\", \"label\": \"#532\"}, {\"href\": \"https://github.com/simonw/datasette/issues/505\", \"label\": \"#505\"}, {\"href\": \"https://github.com/simonw/datasette/compare/0.28...0.29\", \"label\": \"Full list of commits\"}]"}, {"id": "changelog:through-for-joins-through-many-to-many-tables", "page": "changelog", "ref": "through-for-joins-through-many-to-many-tables", "title": "?_through= for joins through many-to-many tables", "content": "The new  ?_through={json}  argument to the Table view allows records to be filtered based on a many-to-many relationship. See  Special table arguments  for full documentation - here's  an example . ( #355 ) \n                 This feature was added to help support  facet by many-to-many , which isn't quite ready yet but will be coming in the next Datasette release.", "breadcrumbs": "[\"Changelog\", \"0.29 (2019-07-07)\"]", "references": "[{\"href\": \"https://latest.datasette.io/fixtures/roadside_attractions?_through={%22table%22:%22roadside_attraction_characteristics%22,%22column%22:%22characteristic_id%22,%22value%22:%221%22}\", \"label\": \"an example\"}, {\"href\": \"https://github.com/simonw/datasette/issues/355\", \"label\": \"#355\"}, {\"href\": \"https://github.com/simonw/datasette/issues/551\", \"label\": \"facet by many-to-many\"}]"}, {"id": "changelog:v0-29-medium-changes", "page": "changelog", "ref": "v0-29-medium-changes", "title": "Easier custom templates for table rows", "content": "If you want to customize the display of individual table rows, you can do so using a  _table.html  template include that looks something like this: \n                 {% for row in display_rows %}\n    <div>\n        <h2>{{ row[\"title\"] }}</h2>\n        <p>{{ row[\"description\"] }}<lp>\n        <p>Category: {{ row.display(\"category_id\") }}</p>\n    </div>\n{% endfor %} \n                 This is a  backwards incompatible change . If you previously had a custom template called  _rows_and_columns.html  you need to rename it to  _table.html . \n                 See  Custom templates  for full details.", "breadcrumbs": "[\"Changelog\", \"0.29 (2019-07-07)\"]", "references": "[]"}], "truncated": false}