Moya Tables

Moya Tables supplies a system of widgets for rendering tables in content definitions.

Installation

Moya Tables is built in to Moya and may be imported via its Python path as follows:

<import py="moya.libs.tables" />

You can install this library with the following:

<install name="tables" lib="moya.tables" />

You won't need to mount Moya Tables, because there are no views. However, there is a test page, which you may mount as follows:

<mount app="tables" mountpoint="test" mount="/tables/"/>

Namespace

Moya Tables uses the namespace http://moyaproject.com/tables.

Introduction

It is entirely possible to generate HTML tables in templates without using this library. The main advantage of Moya Tables is that table cells may contain arbitrary content, which may be difficult to manage with an HTML tag soup.

Widgets

A <table> defines a table in a content definition. For example:

<table xmlns="http://moyaproject.com/tables">
    <!-- table contents go here -->
</table>

To define the columns in a table, add a <columns> tag inside the <table>.

The <columns> tag should contain a number of <header> tags which define a header for each column in the table. For example, the following creates a table with two columns:

<table xmlns="http://moyaproject.com/tables">
    <columns>
        <header>Product</header>
        <header>Stock</header>
    </columns>
</table>

To define the rows for the tables add a <rows> tag containing a <row> tag for each row. The <row> tags should themselves contain a <cell> for each column. A cell may contain simple text, or any other content tags; images, forms, alerts etc. Here's an example:

<table xmlns="http://moyaproject.com/tables">
    <columns>
        <header>Product</header>
        <header>Stock</header>
    </columns>
    <rows>
        <row>
            <cell>Salmon Nigiri Bento</cell>
            <cell>4</cell>
        </row>
        <row>
            <cell>Mixed Sushi Bento</cell>
            <cell>2</cell>
        </row>
    </rows>
</table>

This will create a table with two rows.

While it is possible to add each row individually, it is more common to generate the rows from a sequence, such as a database query. In this case you can supply a src attribute to the <rows> tag, which contains the object to iterate over.

Here's an example which generates the rows from a queryset called products:

<table xmlns="http://moyaproject.com/tables">
    <columns>
        <header>Product</header>
        <header>Stock</header>
    </columns>
    <rows src="products" dst="product">
        <cell>${product.name}</cell>
        <cell>${product.stock}</cell>
    </rows>
</table>

Note that when you use the src attribute in this way, Moya inserts the rows automatically – so you won't need to add <row> tags

Table Style

You can set a CSS style on your <table> with the class attribute. You will probably want to do this if you are using Bootstrap CSS, which doesn't apply any particular style to a table unless it has the class "table". Here's an example:

<table xmlns="http://moyaproject.com/tables" style="table table-striped">
    <columns>
        <header>Product</header>
        <header>Stock</header>
    </columns>
    <rows src="products" dst="product">
        <cell>${product.name}</cell>
        <cell>${product.stock}</cell>
    </rows>
</table>

Sortable Columns

You may generate a clickable header that adds sort information to the query string, with the <sort-header>. Here's an example:

<table xmlns="http://moyaproject.com/tables">
    <columns>
        <sort-header name="product">Product</sort-header>
        <sort-header name="stock">Stock</sort-header>
    </columns>
    <rows src="products" dst="product">
        <cell>${product.name}</cell>
        <cell>${product.stock}</cell>
    </rows>
</table>

This makes both column headers clickable. If you click the Product header, it will link to the same page, with the query string sort=product&order=asc. If you click on the header again it will toggle the order value between asc and desc (for ascending and descending order).

You will still need to implement sorting in the view that gets the products. The sort and order values can be looked up with .request.GET.sort and .request.GET.order.

Customization

You may customize the various components of a table individually with the template attribute on the tags, or project-wide by overriding the template in your project.

Table templates are stored in the template filesystem, in the /moya.tables/ directory. You may list them with the following command:

$ moya fs templates --tree moya.tables

It is also possible to mix table tags with other content tags. For example, if you want to render a template for each row rather than define the cells individually. Here's how you might do that:

<table xmlns="http://moyaproject.com/tables">
    <columns>
        <sort-header name="product">Product</sort-header>
        <sort-header name="stock">Stock</sort-header>
    </columns>
    <rows>
        <moya:node template="/sushifinder/table/rows.html" let:products="products"/>
    </rows>
</table>

The template equivelent of the preceding examples would be something like the following:

{% for product in products %}
<tr>
    <td>${product.name}</td>
    <td>${product.stock}</td>
</tr>
{% endfor %}