| 
									
										
										
										
											2018-04-18 03:12:21 +00:00
										 |  |  | .. _customization:
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Customization
 | 
					
						
							|  |  |  | =============
 | 
					
						
							| 
									
										
										
										
											2017-11-30 17:09:48 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | Datasette provides a number of ways of customizing the way data is displayed.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Custom CSS and JavaScript
 | 
					
						
							|  |  |  | -------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | When you launch Datasette, you can specify a custom metadata file like this::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     datasette mydb.db --metadata metadata.json
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-16 21:32:55 +00:00
										 |  |  | Your ``metadata.json`` file can include links that look like this::
 | 
					
						
							| 
									
										
										
										
											2017-11-30 17:09:48 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     {
 | 
					
						
							|  |  |  |         "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"
 | 
					
						
							|  |  |  |         ]
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The extra 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 stylesheet or JavaScript if the SRI hash
 | 
					
						
							| 
									
										
										
										
											2018-05-26 19:46:24 +00:00
										 |  |  | matches the content served. You can generate hashes using `www.srihash.org <https://www.srihash.org/>`_
 | 
					
						
							| 
									
										
										
										
											2017-11-30 17:09:48 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | Every default template includes CSS classes in the body designed to support
 | 
					
						
							|  |  |  | custom styling.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-09 18:33:14 +00:00
										 |  |  | The index template (the top level page at ``/``) gets this::
 | 
					
						
							| 
									
										
										
										
											2017-11-30 17:09:48 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     <body class="index">
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-09 18:33:14 +00:00
										 |  |  | The database template (``/dbname``) gets this::
 | 
					
						
							| 
									
										
										
										
											2017-11-30 17:09:48 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     <body class="db db-dbname">
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-09 18:33:14 +00:00
										 |  |  | The custom SQL template (``/dbname?sql=...``) gets this::
 | 
					
						
							| 
									
										
										
										
											2017-12-05 16:35:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     <body class="query db-dbname">
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-09 18:33:14 +00:00
										 |  |  | The table template (``/dbname/tablename``) gets::
 | 
					
						
							| 
									
										
										
										
											2017-11-30 17:09:48 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     <body class="table db-dbname table-tablename">
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-09 18:33:14 +00:00
										 |  |  | The row template (``/dbname/tablename/rowid``) gets::
 | 
					
						
							| 
									
										
										
										
											2017-11-30 17:09:48 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     <body class="row db-dbname table-tablename">
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-18 02:11:11 +00:00
										 |  |  | The ``db-x`` and ``table-x`` classes use the database or table names themselves if
 | 
					
						
							| 
									
										
										
										
											2017-11-30 17:09:48 +00:00
										 |  |  | 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.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-09 18:33:14 +00:00
										 |  |  | Some examples::
 | 
					
						
							| 
									
										
										
										
											2017-11-30 17:09:48 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     "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"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-18 02:11:11 +00:00
										 |  |  | ``<td>`` and ``<th>`` elements also get custom CSS classes reflecting the
 | 
					
						
							|  |  |  | database column they are representing, for example::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     <table>
 | 
					
						
							|  |  |  |         <thead>
 | 
					
						
							|  |  |  |             <tr>
 | 
					
						
							|  |  |  |                 <th class="col-id" scope="col">id</th>
 | 
					
						
							|  |  |  |                 <th class="col-name" scope="col">name</th>
 | 
					
						
							|  |  |  |             </tr>
 | 
					
						
							|  |  |  |         </thead>
 | 
					
						
							|  |  |  |         <tbody>
 | 
					
						
							|  |  |  |             <tr>
 | 
					
						
							| 
									
										
										
										
											2018-04-18 02:35:03 +00:00
										 |  |  |                 <td class="col-id"><a href="...">1</a></td>
 | 
					
						
							| 
									
										
										
										
											2018-04-18 02:11:11 +00:00
										 |  |  |                 <td class="col-name">SMITH</td>
 | 
					
						
							|  |  |  |             </tr>
 | 
					
						
							|  |  |  |         </tbody>
 | 
					
						
							|  |  |  |     </table>
 | 
					
						
							| 
									
										
										
										
											2017-11-30 17:09:48 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | Custom templates
 | 
					
						
							|  |  |  | ----------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | By default, Datasette uses default templates that ship with the package.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | You can over-ride these templates by specifying a custom ``--template-dir`` like
 | 
					
						
							|  |  |  | this::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     datasette mydb.db --template-dir=mytemplates/
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Datasette will now first look for templates in that directory, and fall back on
 | 
					
						
							|  |  |  | the defaults if no matches are found.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | It is also possible to over-ride templates on a per-database, per-row or per-
 | 
					
						
							|  |  |  | table basis.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The lookup rules Datasette uses are as follows::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Index page (/):
 | 
					
						
							|  |  |  |         index.html
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Database page (/mydatabase):
 | 
					
						
							|  |  |  |         database-mydatabase.html
 | 
					
						
							|  |  |  |         database.html
 | 
					
						
							| 
									
										
										
										
											2017-12-05 16:35:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Custom query page (/mydatabase?sql=...):
 | 
					
						
							|  |  |  |         query-mydatabase.html
 | 
					
						
							|  |  |  |         query.html
 | 
					
						
							| 
									
										
										
										
											2017-12-09 21:34:46 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Canned query page (/mydatabase/canned-query):
 | 
					
						
							|  |  |  |         query-mydatabase-canned-query.html
 | 
					
						
							|  |  |  |         query-mydatabase.html
 | 
					
						
							|  |  |  |         query.html
 | 
					
						
							| 
									
										
										
										
											2017-11-30 17:09:48 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Table page (/mydatabase/mytable):
 | 
					
						
							|  |  |  |         table-mydatabase-mytable.html
 | 
					
						
							|  |  |  |         table.html
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Row page (/mydatabase/mytable/id):
 | 
					
						
							|  |  |  |         row-mydatabase-mytable.html
 | 
					
						
							|  |  |  |         row.html
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-07 06:11:22 +00:00
										 |  |  |     Rows and columns include on table page:
 | 
					
						
							|  |  |  |         _rows_and_columns-table-mydatabase-mytable.html
 | 
					
						
							|  |  |  |         _rows_and_columns-mydatabase-mytable.html
 | 
					
						
							|  |  |  |         _rows_and_columns.html
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Rows and columns include on row page:
 | 
					
						
							|  |  |  |         _rows_and_columns-row-mydatabase-mytable.html
 | 
					
						
							|  |  |  |         _rows_and_columns-mydatabase-mytable.html
 | 
					
						
							|  |  |  |         _rows_and_columns.html
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-30 17:09:48 +00:00
										 |  |  | 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 - for
 | 
					
						
							|  |  |  | example, a table called "Food Trucks" will attempt to load the following
 | 
					
						
							|  |  |  | templates::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     table-mydatabase-Food-Trucks-399138.html
 | 
					
						
							|  |  |  |     table.html
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-09 21:47:32 +00:00
										 |  |  | You can find out which templates were considered for a specific page by viewing
 | 
					
						
							|  |  |  | source on that page and looking for an HTML comment at the bottom. The comment
 | 
					
						
							|  |  |  | will look something like this::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     <!-- Templates considered: *query-mydb-tz.html, query-mydb.html, query.html -->
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This example is from the canned query page for a query called "tz" in the
 | 
					
						
							|  |  |  | database called "mydb". The asterisk shows which template was selected - so in
 | 
					
						
							|  |  |  | this case, Datasette found a template file called ``query-mydb-tz.html`` and
 | 
					
						
							|  |  |  | used that - but if that template had not been found, it would have tried for
 | 
					
						
							|  |  |  | ``query-mydb.html`` or the default ``query.html``.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-30 17:09:48 +00:00
										 |  |  | 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 %}
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-07 06:11:22 +00:00
										 |  |  | Note the ``default:row.html`` template name, which ensures Jinja will inherit
 | 
					
						
							|  |  |  | from the default template.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-09 18:41:20 +00:00
										 |  |  | The ``_rows_and_columns.html`` template is included on both the row and the table
 | 
					
						
							| 
									
										
										
										
											2018-04-19 05:57:31 +00:00
										 |  |  | page, and displays the content of the row. The default ``_rows_and_columns.html`` template
 | 
					
						
							|  |  |  | `can be seen here <https://github.com/simonw/datasette/blob/master/datasette/templates/_rows_and_columns.html>`_.
 | 
					
						
							| 
									
										
										
										
											2017-12-07 06:11:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | You can provide a custom template that applies to all of your databases and
 | 
					
						
							|  |  |  | tables, or you can provide custom templates for specific tables using the
 | 
					
						
							|  |  |  | template naming scheme described above.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Say for example you want to output a certain column as unescaped HTML. You could
 | 
					
						
							|  |  |  | provide a custom ``_rows_and_columns.html`` template like this::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     <table>
 | 
					
						
							|  |  |  |         <thead>
 | 
					
						
							|  |  |  |             <tr>
 | 
					
						
							|  |  |  |                 {% for column in display_columns %}
 | 
					
						
							|  |  |  |                     <th scope="col">{{ column }}</th>
 | 
					
						
							|  |  |  |                 {% endfor %}
 | 
					
						
							|  |  |  |             </tr>
 | 
					
						
							|  |  |  |         </thead>
 | 
					
						
							|  |  |  |         <tbody>
 | 
					
						
							|  |  |  |         {% for row in display_rows %}
 | 
					
						
							|  |  |  |             <tr>
 | 
					
						
							|  |  |  |                 {% for cell in row %}
 | 
					
						
							|  |  |  |                     <td>
 | 
					
						
							|  |  |  |                         {% if cell.column == 'description' %}
 | 
					
						
							| 
									
										
										
										
											2018-04-19 05:57:31 +00:00
										 |  |  |                             {{ cell.value|safe }}
 | 
					
						
							| 
									
										
										
										
											2017-12-07 06:11:22 +00:00
										 |  |  |                         {% else %}
 | 
					
						
							|  |  |  |                             {{ cell.value }}
 | 
					
						
							|  |  |  |                         {% endif %}
 | 
					
						
							|  |  |  |                     </td>
 | 
					
						
							|  |  |  |                 {% endfor %}
 | 
					
						
							|  |  |  |             </tr>
 | 
					
						
							|  |  |  |         {% endfor %}
 | 
					
						
							|  |  |  |         </tbody>
 | 
					
						
							|  |  |  |     </table>
 |