It is now possible to over-ride templates on a per-database / per-row or per-
table basis.
When you access e.g. /mydatabase/mytable Datasette will look for the following:
- table-mydatabase-mytable.html
- table.html
If you provided a --template-dir argument to datasette serve it will look in
that directory first.
The lookup rules are as follows:
Index page (/):
index.html
Database page (/mydatabase):
database-mydatabase.html
database.html
Table page (/mydatabase/mytable):
table-mydatabase-mytable.html
table.html
Row page (/mydatabase/mytable/id):
row-mydatabase-mytable.html
row.html
If a table name has spaces or other unexpected characters in it, the template
filename will follow the same rules as our custom <body> CSS classes
introduced in 8ab3a169d4 - for example, a table called "Food Trucks"
will attempt to load the following templates:
table-mydatabase-Food-Trucks-399138.html
table.html
It is possible to extend the default templates using Jinja template
inheritance. If you want to customize EVERY row template with some additional
content you can do so by creating a row.html template like this:
{% extends "default:row.html" %}
{% block content %}
<h1>EXTRA HTML AT THE TOP OF THE CONTENT BLOCK</h1>
<p>This line renders the original block:</p>
{{ super() }}
{% endblock %}
Closes#12, refs #153
You can now pass an additional argument specifying a directory to look for
custom templates in.
Datasette will fall back on the default templates if a template is not
found in that directory.
Refs #12, #153
Refs #153
Every template now gets CSS classes in the body designed to support custom
styling.
The index template (the top level page at /) gets this:
<body class="index">
The database template (/dbname/) gets this:
<body class="db db-dbname">
The table template (/dbname/tablename) gets:
<body class="table db-dbname table-tablename">
The row template (/dbname/tablename/rowid) gets:
<body class="row db-dbname table-tablename">
The db-x and table-x classes use the database or table names themselves IF
they are valid CSS identifiers. If they aren't, we strip any invalid
characters out and append a 6 character md5 digest of the original name, in
order to ensure that multiple tables which resolve to the same stripped
character version still have different CSS classes.
Some examples (extracted from the unit tests):
"simple" => "simple"
"MixedCase" => "MixedCase"
"-no-leading-hyphens" => "no-leading-hyphens-65bea6"
"_no-leading-underscores" => "no-leading-underscores-b921bc"
"no spaces" => "no-spaces-7088d7"
"-" => "336d5e"
"no $ characters" => "no--characters-59e024"
A mechanism in the metadata.json format for adding custom CSS and JS urls.
Create a metadata.json file that looks like this:
{
"extra_css_urls": [
"https://simonwillison.net/static/css/all.bf8cd891642c.css"
],
"extra_js_urls": [
"https://code.jquery.com/jquery-3.2.1.slim.min.js"
]
}
Then start datasette like this:
datasette mydb.db --metadata=metadata.json
The CSS and JavaScript files will be linked in the <head> of every page.
You can also specify a SRI (subresource integrity hash) for these assets:
{
"extra_css_urls": [
{
"url": "https://simonwillison.net/static/css/all.bf8cd891642c.css",
"sri": "sha384-9qIZekWUyjCyDIf2YK1FRoKiPJq4PHt6tp/ulnuuyRBvazd0hG7pWbE99zvwSznI"
}
],
"extra_js_urls": [
{
"url": "https://code.jquery.com/jquery-3.2.1.slim.min.js",
"sri": "sha256-k2WSCIexGzOj3Euiig+TlR8gA0EmPjuc79OEeY5L45g="
}
]
}
Modern browsers will only execute the stylsheet or JavaScript if the SRI hash
matches the content served. You can generate hashes using www.srihash.org
Rows page for rows that linked to the same table in more
than one columns were display incorrectly. Fixed that and added a test.
Also introduced /db/table/row-pk.json?_extras=foreign_key_tables
This is used by the new unit test, but is the first example of a new
?_extras=comma-separated-list pattern I am introducing.
This:
?_filter_column_1=name&_filter_op_1=contains&_filter_value_1=hello
&_filter_column_2=age&_filter_op_2=gte&_filter_value_2=12
Now redirects to this:
?name__contains=hello&age__gte=12
This is needed for the filter editing interface, refs #86
URL shortcut for counting rows grouped by one or more columns.
?_group_count=column1&_group_count=column2 works as well.
SQL generated looks like this:
select "qSpecies", count(*) as "count"
from Street_Tree_List
group by "qSpecies"
order by "count" desc limit 100
Or for two columns like this:
select "qSpecies", "qSiteInfo", count(*) as "count"
from Street_Tree_List
group by "qSpecies", "qSiteInfo"
order by "count" desc limit 100
Refs #44
Still todo: clean up code a bunch (it currently fakes being a 'view'), get
foreign key expansion working.
if filter_op contains a __ the value is set to the right hand side.
e.g.
?_filter_column=col&_filter_op=isnull__1&_filter_value=x
Redirects to:
?col__isnull=1
Refs #86
Part of implementing the filters UI (refs #86) - the following:
/trees/Trees?_filter_column=SiteOrder&_filter_op=gt&_filter_value=2
Now redirects to this;
/trees/Trees?SiteOrder__gt=2
The `datasette publish` and `datasette package` commands both now accept an
optional `--build` argument. If provided, this can be used to specify a branch
published to GitHub that should be built into the container.
This makes it easier to test code that has not yet been officially released to
PyPI, e.g.:
datasette publish now mydb.db --branch=master