# live

Source: https://zotonic.com/docs/1323/live

URI: https://zotonic.com/id/1323

Language: en



Live-updating templates driven by MQTT topics.

::: {.note title="Note"}
This scomp is provided by <a href="/id/doc_module_mod_mqtt" class="doc-reference doc-reference-module"><code>module#mod_mqtt</code></a>, which must be enabled.
:::

This tag renders templates that are automatically re-rendered after a publication to an MQTT topic. The tag automatically loads `js/modules/z.live.js` before subscribing, including in dynamic updates.

Example
-------

An example of a template showing the newest content of a resource:

```erlang
{% live template="_detail.tpl" topic=id id=id %}
```

This renders the template `_detail.tpl`. If the resource with id `id` is updated then the template will be replaced with a freshly rendered template.

The tag can subscribe to multiple topics at once.

Add the argument `catinclude` to do a <a href="/id/doc_template_tag_tag_catinclude" class="doc-reference doc-reference-tag"><code>tag#catinclude</code></a> instead of a normal <a href="/id/doc_template_tag_tag_include" class="doc-reference doc-reference-tag"><code>tag#include</code></a>. For a catinclude the argument `id` must be present:

```erlang
{% live template="_detail.tpl" topic=id catinclude id=id %}
```

Arguments
---------

Use either `template` to render a template or, without `template`, supply `postback`, `delegate`, and `target` to call an event handler.

| Argument     | Default                               | Description                                                                      |
| ------------ | ------------------------------------- | -------------------------------------------------------------------------------- |
| `topic`      | None                                  | MQTT topic to subscribe to. Repeat this argument for multiple topics. Accepts a topic string, a list of topic segments, a resource id, or an edge-topic tuple; see Live topics below. |
| `template`   | None                                  | Template to render on notifications. When present, selects template mode.        |
| `catinclude` | `false`                               | Select a category-specific version of `template`, using the resource passed as `id`. |
| `id`         | None                                  | Template variable identifying the resource. Required when using `catinclude`; does not automatically subscribe to that resource's topic. |
| `target`     | Generated element id in template mode | DOM element id to update, without `#`. When supplied, no wrapper is generated: the caller must provide the target element. Required in postback mode. |
| `element`    | `div`                                 | HTML tag for the generated wrapper in template mode. Ignored when `target` is supplied. An empty string suppresses the wrapper; the template must then provide an element with the generated `target` id. |
| `method`     | `update` in template mode             | How to insert or update rendered HTML; see Update methods below. In postback mode the delegate handles rendering. |
| `postback`   | None                                  | Message delivered in `#postback{message = Message, target = Target}` to the delegate. Required when `template` is omitted. |
| `delegate`   | None                                  | Module implementing `event/2` for the postback. Required when `template` is omitted. |
| `throttle`   | `0`                                   | Non-negative integer interval in milliseconds between refreshes during a burst. `0` disables throttling; see Throttling updates below. |

In template mode, arguments other than `topic`, `template`, `catinclude`, `element`, `method`, and `throttle` are passed as template variables. Pass any required variables explicitly: the surrounding template's variables are not automatically inherited. The scomp also supplies `target` and `is_live_update`. The latter is `false` for the initial render and `true` for notification-driven renders.

Update methods
--------------

| Method       | Initial render                             | On notification                               |
| ------------ | ------------------------------------------ | --------------------------------------------- |
| `update`     | Render the template at the tag's location. | Replace the target's contents.                |
| `updateonly` | No template render.                        | Replace the target's contents.                |
| `top`        | No template render.                        | Prepend rendered HTML inside the target.      |
| `bottom`     | No template render.                        | Append rendered HTML inside the target.       |
| `before`     | No template render.                        | Insert rendered HTML before the target.       |
| `after`      | No template render.                        | Insert rendered HTML after the target.        |
| `patch`      | No template render.                        | Update the target through Cotonic's UI model. |

Without an explicit `target`, a wrapper is generated even for methods that do not render the template initially. With an explicit `target`, place the live tag inside that element if using `update` and its initial render is wanted there.

For example, append a rendered item to an existing list on each notification:

```django
<ul id="{{ #items }}"></ul>
{% live topic="bridge/origin/public/items"
        template="_item.tpl" target=#items method="bottom"
%}
```

In notification-driven template renders, a map or proplist MQTT payload is available as query arguments (`q`). Other payload values are available as `q.payload`. These values are untrusted input: escape them when outputting HTML.

To handle notifications in Erlang instead of rendering a template:

```django
<div id="{{ #status }}"></div>
{% live topic="bridge/origin/public/status"
        postback={refresh_status id=id}
        delegate="mod_example" target=#status throttle=3000
%}
```

The delegate receives the configured message and target, and can read the notification's topic and MQTT message using `z_context:get_q/2` with the binary keys `topic` and `message`. Extra live-tag arguments are not automatically added to the postback message; include them in `postback={...}` explicitly. The target must remain in the DOM for the subscription to stay active.

Throttling updates
------------------

Use `throttle=3000` to limit refreshes during a burst to once every three seconds. The first notification refreshes after a short delay (at most 100 milliseconds), then the full interval starts from that refresh. After no notifications for a full interval, the next notification refreshes quickly again. Notifications are combined using the latest topic and message. Continuous events do not postpone the refresh, and the last event is included even if events stop. Initial rendering is unchanged. The default is `0` (no throttling).

The interval is shared by all topics on one `live` tag. Separate `live` tags have independent intervals. The argument applies to both template rendering and the `postback`/`delegate` form of the `live` tag; it is not passed to the rendered template as a variable. Throttling combines browser refresh requests, not the MQTT publications themselves.

Use this for templates showing current state, not event-by-event inserts:

```django
{% live template="_detail.tpl" topic=id id=id throttle=3000 %}
```

Live topics
-----------

Any MQTT topic can be used. The topics are interpreted as local to the page. There are three special topics:

- Use any integer to map to the resource’s update topic. For example if id is `1234` then the topic will be `bridge/origin/model/rsc/event/1234`
- Use the tuple `{object id=...}` to listen to changes of outgoing connections from a page. An example of a mapped topic is bridge/origin/model/edge/event/1234/o/+\`. Use the tuple `{object id=... predicate=...}` to listen to changes of a specific predicate of a page. An example of a mapped topic is `bridge/origin/model/edge/event/1234/o/author`
- Use the tuple `{subject id=... }` to listen to changes of incoming connections to a page. An example of a mapped topic is `bridge/origin/model/edge/event/1234/s/author`

Note that the topics refer to *client side topics*, that is why the bridge is used to subscribe to server side model events.

It is possible to subscribe to client topics like `"my/local/topic"` and have the actions triggered by publish to `cotonic.broker.publish("my/local/topic", {});` (with any payload).

Live actions
------------

It is possible to wire actions or postbacks to a MQTT topic.

Use the <a href="/id/doc_template_scomp_scomp_wire" class="doc-reference doc-reference-scomp"><code>scomp#wire</code></a> with argument `type={mqtt topic=... topic=...}` to connect to one or more MQTT topics. Add `throttle` inside `type={mqtt ...}` to combine rapid notifications before executing the wire's actions and postback. It uses the same millisecond interval, quick first event, and idle reset as the live tag. All topics of one wire share an interval; separate wires are independent. The latest notification supplies the event arguments. Omit `throttle` or use `0` for immediate execution of every notification:

```django
{% wire type={mqtt topic="bridge/origin/public/hello" throttle=3000}
        action={growl text="hello"}
%}
```

And in Erlang this will trigger the above *growl*:

```erlang
z_mqtt:publish(<<"public/hello">>, <<>>, z:c(mysite)).
```

License: 

Attribution: 

Related resources: https://zotonic.com/api/agent/related/1323?language=en


## API access

- [API help](<https://zotonic.com/api-help>)
- [OpenAPI specification](<https://zotonic.com/openapi.json>)
- [This resource as JSON](<https://zotonic.com/api/agent/resource/1323?language=en>)
