diff --git a/datasette/app.py b/datasette/app.py
index 35dbda51..de6d0b91 100644
--- a/datasette/app.py
+++ b/datasette/app.py
@@ -682,6 +682,11 @@ class TableView(RowTableShared):
'display_columns': display_columns,
'filter_columns': filter_columns,
'display_rows': await self.make_display_rows(name, hash, table, rows, display_columns, pks, is_view, use_rowid, is_row_display=False),
+ 'custom_rows_and_columns_templates': [
+ '_rows_and_columns-{}-{}.html'.format(to_css_class(name), to_css_class(table)),
+ '_rows_and_columns-table-{}-{}.html'.format(to_css_class(name), to_css_class(table)),
+ '_rows_and_columns.html',
+ ]
}
return {
@@ -741,6 +746,11 @@ class RowView(RowTableShared):
'foreign_key_tables': await self.foreign_key_tables(name, table, pk_values),
'display_columns': columns,
'display_rows': await self.make_display_rows(name, hash, table, rows, columns, pks, is_view=False, use_rowid=use_rowid, is_row_display=True),
+ 'custom_rows_and_columns_templates': [
+ '_rows_and_columns-{}-{}.html'.format(to_css_class(name), to_css_class(table)),
+ '_rows_and_columns-row-{}-{}.html'.format(to_css_class(name), to_css_class(table)),
+ '_rows_and_columns.html',
+ ]
}
data = {
diff --git a/datasette/templates/row.html b/datasette/templates/row.html
index b0b527ff..b338f007 100644
--- a/datasette/templates/row.html
+++ b/datasette/templates/row.html
@@ -22,7 +22,7 @@
This data as .json, .jsono
-{% include "_rows_and_columns.html" %}
+{% include custom_rows_and_columns_templates %}
{% if foreign_key_tables %}
Links from other tables
diff --git a/datasette/templates/table.html b/datasette/templates/table.html
index a371ca69..6b014c12 100644
--- a/datasette/templates/table.html
+++ b/datasette/templates/table.html
@@ -74,7 +74,7 @@
This data as .json, .jsono
-{% include "_rows_and_columns.html" %}
+{% include custom_rows_and_columns_templates %}
{% if next_url %}
Next page
diff --git a/docs/custom_templates.rst b/docs/custom_templates.rst
index 425fd09a..fc20e724 100644
--- a/docs/custom_templates.rst
+++ b/docs/custom_templates.rst
@@ -120,6 +120,16 @@ The lookup rules Datasette uses are as follows::
row-mydatabase-mytable.html
row.html
+ 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
+
If a table name has spaces or other unexpected characters in it, the template
filename will follow the same rules as our custom ```` CSS classes - for
example, a table called "Food Trucks" will attempt to load the following
@@ -140,5 +150,59 @@ content you can do so by creating a ``row.html`` template like this::
{{ super() }}
{% endblock %}
-Note the ``default:row.html`` template name, which ensures Jinja will inherit from the
-default template.
+Note the ``default:row.html`` template name, which ensures Jinja will inherit
+from the default template.
+
+The `_rows_and_columns.html` template is included on both the row and the table
+page, and displays the content of the row. The default template looks like this::
+
+
+
+
+ {% for column in display_columns %}
+ | {{ column }} |
+ {% endfor %}
+
+
+
+ {% for row in display_rows %}
+
+ {% for cell in row %}
+ | {{ cell.value }} |
+ {% endfor %}
+
+ {% endfor %}
+
+
+
+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::
+
+
+
+
+ {% for column in display_columns %}
+ | {{ column }} |
+ {% endfor %}
+
+
+
+ {% for row in display_rows %}
+
+ {% for cell in row %}
+ |
+ {% if cell.column == 'description' %}
+ !!{{ cell.value|safe }}
+ {% else %}
+ {{ cell.value }}
+ {% endif %}
+ |
+ {% endfor %}
+
+ {% endfor %}
+
+