Handle a browser event with a wire
Use scomp#wire to connect a browser event to an action or a server postback. Give the target element a stable ID within the rendered page.
Use scomp#wire to connect a browser event to an action or a server postback. Give the target element a stable ID within the rendered page.
<button id="show-help" type="button">{_ Show help _}</button>
<div id="garden-help" style="display:none">{_ Choose a sunny spot. _}</div>
{% wire id="show-help" action={show target="garden-help"} %}
Use a server postback when the action needs server data or writes content. A client-side action alone cannot authorize a write. Check the browser console and the server logs when an event appears to do nothing.
Use a base template with the standard JavaScript includes and a final {% script %}; enable mod_wires on the site. Put the example inside its content block. Click Show help and expect the hidden text to appear without navigation. If this partial can appear twice, use generated template IDs such as #show_help rather than repeating the literal ID.
Use Cotonic and MQTT for browser messaging
Use the existing Cotonic browser models and Zotonic MQTT bridge when components need to communicate through topics. First identify whether the topic stays inside the browser or crosses to the server.
Define a small payload and a clear reply contract. Subscribe before requesting data when the response can arrive immediately. Clean up component subscriptions when their lifetime ends, and handle reconnects without duplicating actions.
Server-side topic access must follow the site's permission rules. A topic name is not a secret or an access check.
With the greeting model from the model task active, try this read in the browser console:
cotonic.ready.then(() =>
cotonic.broker.call("bridge/origin/model/garden/get/greeting", {})
).then(reply => console.log(reply.payload));
Inspect the reply's status and result; expect the greeting on success. An error or disconnected bridge is not an empty greeting. The bridge/origin/ prefix crosses to the site's server model, while a browser-local model such as model/location stays in the browser. Use cotonic#location for the latter's topic contract. Do not insert response text as HTML without escaping it.
Expose an operation through an API
Start from the site's existing model API or controller patterns. Specify the method, input fields, response shape, and errors before connecting a browser or external client.
Use a read operation for retrieval and an appropriate write operation for changes. Apply authentication and authorization to each operation. Test malformed input and access denial as well as a successful response.
Keep transport details out of shared domain functions so the same operation can serve a template, event handler, or API safely. See module#mod_oauth2, Expose data through a model, and Keep permission checks at the boundary.
The greeting model provides a read-only first check. On the site's hostname, request:
GET /api/model/garden/get/greeting
Expect a JSON success response with the greeting as its result. Confirm the HTTP status and response body. Request an unknown path too; the model should return its unknown_path error. This uses the public example from the model task, so no token is required for that particular value.
For protected operations, use the authentication mechanism supported by controller#controller_api, for example an appropriately scoped OAuth token. Authentication identifies the caller; the model still must authorize access. Keep tokens out of URLs and example files. Read the controller reference for response envelopes, HTTP methods and request-body handling before adding writes.