{datatable} writes a whole table from rows of data: a header from the field
names, a body, an optional totals row, header links that sort and page links that page - all
on the server, without JavaScript. The rows come from data= (a
{data} store, a page array or a _data
file, as for {chart}), or, as a pair, from the content:
JSON, YAML, XML or CSV, told apart on sight. The tag writes the table once - it does not
iterate the rows like a data tag does.
columns= picks the fields and their order, labels= gives their
headers; otherwise every field of the first row shows, its name made a headline. A column
whose values are all numbers is right-aligned, written with the most decimals any of its
values has and grouped by thousands - unless its name says it identifies (id,
number, code, year ...), then the digits stand as
they are. format= gives a column a pipe instead, run as
{echo $value | pipe}. totals= sums columns in a last row, over all
rows. Everything from the data is escaped.
With sortable each header is a link to the same page with
?sort=column&dir=asc or desc. Only a column the table shows is
accepted - anything else leaves the rows as they came - and the sort is stable; the sorted
column carries aria-sort. rows= shows that many rows a page with
page links below, built from the {pager}'s items. The
links keep the request's other values. query= prefixes the three request
names, so two tables on one page sort and page apart.
A table without rows answers nothing, and its @else@ part shows. Under the
strict check these are errors: no data at all, a column no row has, a totals= or
format= naming a column the table does not show, a total of a column that is not
numbers, a number of labels that differs from the number of columns, and rows=
below 1.