``: it can be a ````, ``
`` or any other
element that wraps the HTML for that row. Datasette uses this attribute to find
the element to remove after a delete, or replace after an edit. Any edit or
delete controls should be rendered inside that same element.
The ``_action_menu.html`` template renders the action menus used by database,
table, query and row pages. Plugin-provided actions can be link dictionaries
with ``href`` and ``label`` keys, or button dictionaries using ``{"type":
"button", "label": "...", "attrs": {...}}`` for JavaScript-backed interactions.
Both shapes can include an optional ``description`` key. Custom
``_action_menu.html`` templates should preserve support for both link and button
action items.
.. _custom_pages:
Custom pages
------------
You can add templated pages to your Datasette instance by creating HTML files in a ``pages`` directory within your ``templates`` directory.
For example, to add a custom page that is served at ``http://localhost/about`` you would create a file in ``templates/pages/about.html``, then start Datasette like this::
datasette mydb.db --template-dir=templates/
You can nest directories within pages to create a nested structure. To create a ``http://localhost:8001/about/map`` page you would create ``templates/pages/about/map.html``.
.. _custom_pages_parameters:
Path parameters for pages
~~~~~~~~~~~~~~~~~~~~~~~~~
You can define custom pages that match multiple paths by creating files with ``{variable}`` definitions in their filenames.
For example, to capture any request to a URL matching ``/about/*``, you would create a template in the following location::
templates/pages/about/{slug}.html
A hit to ``/about/news`` would render that template and pass in a variable called ``slug`` with a value of ``"news"``.
If you use this mechanism don't forget to return a 404 if the referenced content could not be found. You can do this using ``{{ raise_404() }}`` described below.
Templates defined using custom page routes work particularly well with the ``sql()`` template function from `datasette-template-sql `__ or the ``graphql()`` template function from `datasette-graphql `__.
.. _custom_pages_headers:
Custom headers and status codes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Custom pages default to being served with a content-type of ``text/html; charset=utf-8`` and a ``200`` status code. You can change these by calling a custom function from within your template.
For example, to serve a custom page with a ``418 I'm a teapot`` HTTP status code, create a file in ``pages/teapot.html`` containing the following:
.. code-block:: jinja
{{ custom_status(418) }}
Teapot
I'm a teapot
To serve a custom HTTP header, add a ``custom_header(name, value)`` function call. For example:
.. code-block:: jinja
{{ custom_status(418) }}
{{ custom_header("x-teapot", "I am") }}
Teapot
I'm a teapot
You can verify this is working using ``curl`` like this::
curl -I 'http://127.0.0.1:8001/teapot'
HTTP/1.1 418
date: Sun, 26 Apr 2020 18:38:30 GMT
server: uvicorn
x-teapot: I am
content-type: text/html; charset=utf-8
.. _custom_pages_404:
Returning 404s
~~~~~~~~~~~~~~
To indicate that content could not be found and display the default 404 page you can use the ``raise_404(message)`` function:
.. code-block:: jinja
{% if not rows %}
{{ raise_404("Content not found") }}
{% endif %}
If you call ``raise_404()`` the other content in your template will be ignored.
.. _custom_pages_redirects:
Custom redirects
~~~~~~~~~~~~~~~~
You can use the ``custom_redirect(location)`` function to redirect users to another page, for example in a file called ``pages/datasette.html``:
.. code-block:: jinja
{{ custom_redirect("https://github.com/simonw/datasette") }}
Now requests to ``http://localhost:8001/datasette`` will result in a redirect.
These redirects are served with a ``302 Found`` status code by default. You can send a ``301 Moved Permanently`` code by passing ``301`` as the second argument to the function:
.. code-block:: jinja
{{ custom_redirect("https://github.com/simonw/datasette", 301) }}
.. _custom_pages_errors:
Custom error pages
------------------
Datasette returns an error page if an unexpected error occurs, access is forbidden or content cannot be found.
You can customize the response returned for these errors by providing a custom error page template.
Content not found errors use a ``404.html`` template. Access denied errors use ``403.html``. Invalid input errors use ``400.html``. Unexpected errors of other kinds use ``500.html``.
If a template for the specific error code is not found a template called ``error.html`` will be used instead. If you do not provide that template Datasette's `default error.html template `__ will be used.
The error template will be passed the following context:
``status`` - integer
The integer HTTP status code, e.g. 404, 500, 403, 400.
``error`` - string
Details of the specific error, usually a full sentence.
``title`` - string or None
A title for the page representing the class of error. This is often ``None`` for errors that do not provide a title separate from their ``error`` message.