Datasette gives published databases their own presentation
Datasette 0.14 adds template overrides, static assets and metadata scoped to databases and tables. Publishers can adapt the interface and explain particular datasets while retaining the generated browsing tools.
A generated database interface knows the table names, but it does not know how a publisher wants to explain them. Datasette 0.14, released on 10 December, adds custom templates and a richer metadata format. A database publication can now carry its own descriptions and presentation without requiring every page to be rewritten.
The release provides several levels of intervention. Publishers can add stylesheets, replace a general page template or override the template for a particular table. Metadata can describe an individual database or table. These choices let a small publication retain the default interface where it works and supply specific context where the dataset requires it.
I like this direction because publishing a database involves more than exposing rows. A reader needs to understand what the values represent and where they came from. Keeping those explanations near the actual tables makes the database more useful without hiding its relational structure.
Template lookup follows the resource
The new --template-dir option tells Datasette where to find custom templates. It falls back to its default templates when a custom file is absent. The release describes lookup rules for index, database, table and row pages, with more specific names preceding the general template name.
For a table at /mydatabase/mytable, Datasette considers table-mydatabase-mytable.html before table.html. A publisher can therefore change the presentation of one table without changing every table page. A general override remains available for a change intended to apply throughout the publication.
Jinja inheritance gives another degree of control. A custom template can extend default:row.html and use super() to retain the original content block. This avoids copying the whole default template merely to add surrounding explanation. It also makes the intended scope of the customization visible in the template itself.
Names containing spaces or unexpected characters need a predictable mapping to filenames. Datasette strips invalid characters and appends a short digest when needed to distinguish names that otherwise normalize to the same string. The release uses the same naming rules for template lookup and resource-specific CSS classes. A table's display name does not have to be a valid CSS identifier for it to receive a distinct styling hook.
Styles can target individual database pages
The new body classes identify both page type and resource. A table page has a table class together with classes identifying its database and table. A row page has its own page-type class. These hooks let a stylesheet target a particular part of the generated interface without replacing its markup.
The metadata format accepts extra_css_urls and extra_js_urls. The server links those assets in each page's head. A publisher can also supply subresource integrity hashes, which let supporting browsers check that an asset's contents match the expected digest before using it.
Static files need not live on another server. The new --static option maps a URL mountpoint to a directory. The 0.14 README includes the option in both serving and packaging commands. For a local directory named assets, a publisher can expose it under a matching URL prefix.
datasette serve data.db --template-dir templates --static assets:assets
This command assumes that the database and directories already exist. It selects the custom-template directory and gives the service a location for static assets. A template can then refer to those published files as part of its presentation.
Metadata describes a particular table
The expanded JSON structure has a databases object, with tables nested under their database. Titles and descriptions can apply at those narrower scopes. The release supports plain descriptions and HTML descriptions, alongside source and licensing information.
A new datasette skeleton command generates an initial metadata file with database and table entries ready to fill in. That reduces the work of reproducing the schema's names in a separate configuration file. The publisher still supplies the explanation, since a column name cannot establish the meaning or provenance of its contents.
I find per-table descriptions particularly useful because databases often contain tables with different roles. A publication can explain one table's source while giving another table a different description. The structure permits that distinction without requiring separate sites or changes to the stored data.
The same metadata file can define named canned queries. Datasette lists them in a Queries section below Views on the database page. These definitions give readers prepared entry points to useful SQL questions. They also keep those publication-specific query definitions in the surrounding metadata instead of requiring every one to become a database view.
Packaging includes the presentation
The package and publish commands now accept --static and --template-dir. They copy the selected directories into the resulting deployment image. This makes the presentation part of the publication that travels with the database, rather than a local customization that disappears when the publisher deploys it.
The release also emits an HTML comment showing which templates it considered for a page. That is a practical diagnostic for a resource-specific override. If a customized page does not appear, the publisher can inspect the lookup candidates instead of guessing which filename the resource name produced.
The resulting workflow can stay incremental. A publisher can begin with descriptions and a stylesheet, add a specialized table template when needed and package those files with the data. Datasette continues to supply the general browsing interface while the publisher supplies the explanations and presentation choices specific to the database.