Skip to main content

Weblets

A weblet is a UI panel embedded within a ZeyOS entity detail view. When a user opens a contact, ticket, account, or any other entity record, weblets appear as tabs or panels alongside the standard entity fields. They are the primary extension point for adding custom interfaces to ZeyOS.

How weblets work

Weblets are iXML files stored in the weblets/ directory of a ZeyOS application. Each weblet is registered in zeyos.app.json and linked to one or more entity types. When a user navigates to a matching entity record, ZeyOS executes the weblet's iXML and renders the result inside the entity detail view.

Context variables

Inside a weblet, several context variables are available:

VariableDescription
$IDThe ID of the current entity record
$ENTITYThe entity type (e.g., contacts, tickets)
$EXTDATAPreviously saved form data for this record
$REQUESTHTTP request parameters
$APPSETTINGSApplication settings for the current instance

Two approaches

Form-based weblets use the form namespace to build native ZeyOS input controls declaratively. The form engine handles rendering, layout, and data persistence through EXTDATA. This is the fastest way to build data-entry interfaces.

Custom weblets output raw HTML, CSS, and JavaScript using iXML's <output> command. This gives you full control over the UI, including custom visualizations, interactive dashboards, or integration with external JavaScript libraries.

Custom HTML weblets

A custom weblet outputs HTML directly. You can use any standard web technology — HTML, CSS, JavaScript — and call back to ZeyOS services via AJAX.

Basic structure

XML
<output><![CDATA[
<style>
.dashboard { padding: 16px; font-family: sans-serif; }
.metric { display: inline-block; margin: 8px; padding: 16px; background: #f5f5f5; border-radius: 4px; }
.metric-value { font-size: 24px; font-weight: bold; }
.metric-label { font-size: 12px; color: #666; }
</style>
]]></output>

<!-- Fetch data for the current entity -->
<db:select var_result="stats" type="self" entity="transactions">
<db:fields>
<db:field>COUNT(*) AS total</db:field>
<db:field>SUM(t.netamount) AS revenue</db:field>
</db:fields>
<db:table alias="t">transactions</db:table>
<db:is field="t.account">$ID</db:is>
</db:select>

<output><![CDATA[
<div class="dashboard">
<div class="metric">
<div class="metric-value">]]>$stats.total<![CDATA[</div>
<div class="metric-label">Transactions</div>
</div>
<div class="metric">
<div class="metric-value">]]>$stats.revenue<![CDATA[ €</div>
<div class="metric-label">Total Revenue</div>
</div>
</div>
]]></output>

Calling services from JavaScript

Custom weblets can interact with the application's remotecall services using AJAX. This enables dynamic, interactive interfaces:

XML
<output><![CDATA[
<div id="app">
<button onclick="loadData()">Refresh</button>
<div id="result"></div>
</div>

<script>
function loadData() {
fetch('./remotecall/my-service/]]>$ID<![CDATA[')
.then(r => r.json())
.then(data => {
document.getElementById('result').innerHTML =
JSON.stringify(data, null, 2);
});
}
</script>
]]></output>
tip

For complex custom UIs, keep the iXML weblet thin — use it only to inject context variables (like $ID and $APPSETTINGS) into the HTML, and handle all business logic in remotecall services that return JSON.

When to use which approach

ScenarioApproach
Data-entry form with standard fieldsForm namespace
Custom dashboard or visualizationCustom HTML weblet
Interactive UI with real-time updatesCustom HTML + remotecall services
Simple read-only data displayEither — forms with readonly fields or custom HTML
Generating downloadable filesExports