Exports
Exports are a special type of weblet that generate downloadable data (CSV, Excel, PDF, etc.) from entity list views. What makes exports unique is the tempfile selector — a mechanism that passes the user's current view state (filters, search terms, and manual selections) into your iXML script, so the export contains exactly the records the user expects.
How the tempfile selector works
When a user triggers an export from an entity list view, ZeyOS:
- Collects all record IDs matching the current view — respecting active filters, search queries, and any manually selected rows
- Writes those IDs into a temporary file
- Passes the temp file's ID to your export script via
$REQUEST.tempfile
Your script reads this selector and uses it to query exactly the right records:
<!-- Read the list of IDs from the tempfile -->
<temp:read id="$REQUEST.tempfile" var_struct="selector" />
The var_struct="selector" attribute parses the temp file content into a structure that can be used directly with db:in to filter a database query.
Basic export pattern
The typical export follows three steps: read the selector, query the data, and format the output.
<!-- 1. Read the selector from the tempfile -->
<temp:read id="$REQUEST.tempfile" var_struct="selector" />
<!-- 2. Query the records matching the selection -->
<db:select var_result="rows" type="assoc">
<db:fields>
<db:field>a.lastname</db:field>
<db:field>a.firstname</db:field>
<db:field>t.date</db:field>
<db:field>t.transactionnum</db:field>
<db:field>t.status</db:field>
<db:field>t.netamount</db:field>
</db:fields>
<db:table alias="t">transactions</db:table>
<db:join>
<db:inner alias="a" table="accounts" field1="t.account" field2="a.ID" />
</db:join>
<db:in field="a.ID" var="selector" />
<db:orderby>
<db:orderfield>a.lastname</db:orderfield>
</db:orderby>
</db:select>
<!-- 3. Format and output (e.g., as CSV) -->
<set var="return.contenttype">text/csv</set>
<set var="return.filename">export.csv</set>
<output>Last Name,First Name,Date,Transaction No.,Status,Net Amount</output>
<foreach var="rows" var_value="row">
<output>
$row.lastname,$row.firstname,$row.date,$row.transactionnum,$row.status,$row.netamount</output>
</foreach>
The selector and db:in
The key integration point is <db:in> — it takes the selector variable and generates a SQL IN (...) clause that filters the query to only the selected IDs. This works with any entity field, not just ID:
<db:in field="t.ID" var="selector" />
You can combine db:in with additional db:is conditions to further narrow results:
<db:select var_result="rows" type="assoc">
<db:fields>
<db:field>t.transactionnum</db:field>
<db:field>t.netamount</db:field>
</db:fields>
<db:table alias="t">transactions</db:table>
<db:in field="t.ID" var="selector" />
<db:is field="t.status">2</db:is>
</db:select>
Excel export
For structured exports, use the Excel namespace to generate .xlsx files:
<temp:read id="$REQUEST.tempfile" var_struct="selector" />
<db:select var_result="contacts" type="assoc">
<db:fields>
<db:field>lastname</db:field>
<db:field>firstname</db:field>
<db:field>email</db:field>
<db:field>phone</db:field>
</db:fields>
<db:table>contacts</db:table>
<db:in field="ID" var="selector" />
<db:orderby>
<db:orderfield>lastname</db:orderfield>
</db:orderby>
</db:select>
<excel:create var="wb">
<excel:sheet title="Contacts">
<!-- Header row -->
<excel:row>
<excel:cell style="bold">Last Name</excel:cell>
<excel:cell style="bold">First Name</excel:cell>
<excel:cell style="bold">Email</excel:cell>
<excel:cell style="bold">Phone</excel:cell>
</excel:row>
<!-- Data rows -->
<foreach var="contacts" var_value="c">
<excel:row>
<excel:cell>$c.lastname</excel:cell>
<excel:cell>$c.firstname</excel:cell>
<excel:cell>$c.email</excel:cell>
<excel:cell>$c.phone</excel:cell>
</excel:row>
</foreach>
</excel:sheet>
</excel:create>
<set var="return.contenttype">application/vnd.openxmlformats-officedocument.spreadsheetml.sheet</set>
<set var="return.filename">contacts_export.xlsx</set>
<output>$wb</output>
Tips
- The selector respects whatever the user sees in their view — if they've filtered by status, date range, or search term, only matching IDs are included.
- If the user manually selected specific rows (via checkboxes), only those IDs are passed.
- Always use
var_struct="selector"withtemp:readso the IDs are in the correct format fordb:in. - Set
return.contenttypeandreturn.filenameto control the download behavior in the browser.