Moya Admin creates a fully features administration site, which allows users (with admin permissions) to query and manage objects stored in the database.
The Moya Admin library is built in to Moya and may be imported via its Python path as follows:
<import py="moya.libs.forms"/>
The above line should be in your <server> declaration.
You can install the library with the following:
<install name="admin" lib="moya.admin" mount="/admin/" />
This will install Moya Admin and mount it on /admin/.
Moya Admin uses the namespace http://moyaproject.com/admin
.
If you visit the admin site (on /admin/) you will see a list of modules in a panel. These are headings which contain a sub-menu of table views which display objects stored in the database. From a table view you can search the database for a particular object, and also create / edit / delete items from the database.
Libraries can advertise what modules / tables they support and customize admin functionality as well as look and feel. You won't need to do any particular configuration for a library to use the admin sites; installing a library is enough to register with the admin sites.
A library can advertise the modules it wishes to add to the admin site by adding a <module> tag anywhere in the library code – by convention in a file called admin.xml
. There is typically only one module per application, but it is entirely possible to have more than one.
Here's how you might create a module in your library:
<module xmlns="http://moyaproject.com/admin"slug="sushi-shop" title="Sushi Shop" description="Manage Sushi Products"></module>
This will create a link in the admin panel using these details. If you click on a module link in admin (as apposed to just expanding the menu), you will see a simple title page. You can customize this page by setting the content
attribute to your new content. Your custom content should extend moya.admin#content.cover
, and contain a section called content
. Here's an example:
<module xmlns="http://moyaproject.com/admin" content="content.custom.admin"slug="sushi-shop" title="Sushi Shop" description="Manage Sushi Products"></module><content libname="content.custom.admin" extends="moya.admin#content.cover"><section name="content"><markdown>Sushi Shop==========Get your sushi here!</markdown></section></content>
A <module> should contain one or more <link> tags. These reference <table> tags which define a table view. See the next section for an overview of defining tables.
Tables are advertised with the <table> tag which sets the title
. slug
, and model
for the table view. The model should be a reference to the <model> you want to list in the table.
Within the <table> should be a sequence of <column> tags which define the columns to be displayed in the table. Here's an example of a table definition with two columns:
<table libname="admintable.products" slug="products"title="Sushi Products" model="#Product"><column title="Product" sort="name">${object.name}</column><column title="Stock" sort="stock">${object.stock} piece(s)</column></table>
When Moya Admin renders a table, it iterates through each object in the database and creates table cells from the <column> tags, to which it passes the current object as a value called object
. Columns may contain simple expressions, for example ${object.name}
to display the name
field of the database object, or, any other content tags. This makes tables infinitely customizable as you can put text, images, widgets, forms or any other renderable content inside a cell.
To display this table in the modules panel, you would add a <link> to your module definition. Here's how to add the products table to the Sushi Shop model:
<module xmlns="http://moyaproject.com/admin"slug="sushi-shop" title="Sushi Shop" description="Manage Sushi Products"><link to="admintable.products" title="Products"/></module>
You can add a search field to the table by setting the search
attribute on the table
. This should be a database expression referencing the value q
which contains the text the user searched for. Here's how we would add search capabilities to the Sushi Products table:
<table libname="admintable.products" slug="products"search="#Product.name == q"title="Sushi Products" model="#Product"><column title="Product" sort="name">${object.name}</column><column title="Stock" sort="stock">${object.stock} piece(s)</column></table>
The db expression, #Product.name == q
matches all products a name field set to the search query. You can use a more complicated db expression to search multiple fields, or to do more relaxed queries. For instance #Product.name icontains q
, would match any products with a name containing the search substring.
By default, Moya Admin will list all objects of the specified type in the table. It is also possible to restrict the query to objects matching a db expression. You might want to do this if you want several tables, each showing a different subset of objects. To filter objects in a table, set the filter
attribute to a db expression. Here's how you would create a table view that displayed only the sushi products in stock:
<table libname="admintable.products_in_stock" slug="products_on_stock"search="#Product.name == q"description="Products in stock"filter="#Product.stock gt 0"title="Sushi Products" model="#Product"><column title="Product" sort="name">${object.name}</column><column title="Stock" sort="stock">${object.stock} piece(s)</column></table>