Sessel expression binding
A Sessel expression binding evaluates a Sessel expression during server-side composition and exposes the result as a named variable to templates. For the JavaScript peer, see JavaScript expression binding.
When to reach for it
Use expression bindings to compute values — averages, filtered lists, counts — directly in HTML without application code. They complement resource bindings, which select elements but cannot compute over them.
Namespace declaration
Declare the Sessel binding namespace on an ancestor element:
<html xmlns:e="https://pagelove.org/Binding/Sessel">
The namespace URI must be exactly https://pagelove.org/Binding/Sessel. The prefix (here e) can be any valid XML prefix.
Attribute form
| Part | Role |
|---|---|
Prefix (e:) |
The declared namespace prefix |
| Attribute name | The variable name exposed to templates |
| Attribute value | A Sessel expression evaluated at serve time |
<div e:total="${[itemprop="price"]}.sum()"
e:count="${[itemprop="price"]}.count()"
pagelove:template="text/liquid">
<p>{{ count }} products totalling ${{ total }}</p>
</div>
Declaration-order evaluation
Attributes evaluate left to right in source order. A bound name is available to subsequent expressions on the same element:
<div e:total="${[itemprop="price"]}.sum()"
e:count="${[itemprop="price"]}.count()"
e:average="total / count"
pagelove:template="text/liquid">
<p>Average price: ${{ average }}</p>
</div>
Here total and count resolve first. When average evaluates, both names are already in scope.
Scope
Bindings follow element ancestry:
- A binding is visible to the declaring element and all its descendants.
- Sibling elements and their descendants cannot see it.
- When the same name appears at multiple levels, the nearest ancestor wins.
<section xmlns:e="https://pagelove.org/Binding/Sessel"
e:sitecount="${div.item}.count()">
<!-- sitecount is available here and in all descendants -->
<div e:localcount="${div.item} from self).count()"
pagelove:template="text/liquid">
<!-- Both sitecount and localcount are available -->
<p>{{ localcount }} of {{ sitecount }} items</p>
</div>
<div pagelove:template="text/liquid">
<!-- sitecount is available, localcount is NOT (it is on a sibling) -->
<p>{{ sitecount }} total items</p>
</div>
</section>
The three bindings compared
Sessel is one of three binding namespaces that attach a named value to an element during composition:
| Aspect | Resource binding | Sessel expression binding | JavaScript expression binding |
|---|---|---|---|
| Namespace | https://pagelove.org/Binding/CSS |
https://pagelove.org/Binding/Sessel |
https://pagelove.org/Binding/JavaScript |
| Value | CSS selector (returns matching elements) | Sessel expression (returns any value) | JavaScript expression (returns any value) |
| Can compute | No — selects elements only | Yes — arithmetic, aggregation, filtering | Yes — full JavaScript expression |
| Can reference other bindings | No | Yes — later bindings can reference earlier ones | Yes — earlier bindings read as bare identifiers |
All three may appear on the same element. Resource bindings resolve first, then expression bindings evaluate in declaration order.
Examples
Count and sum from site data
Expression bindings can aggregate values across multiple documents. Given two product pages, a summary page uses count() and sum() to compute totals:
{% example "setup-summary", "body" %}
Fetching the summary page renders the computed values:
GET /sessel-expr-summary.html
HTTP/1.1 200
<!DOCTYPE html>
<html>
<body>
<div>
<p>Count: 2</p>
<p>Sum: 100.0</p>
</div>
</body>
</html>
Error cases
| Condition | Result |
|---|---|
| Sessel expression fails to compile | Request fails with an error during composition |
| Expression references an undefined variable name | Request fails with an error during composition |
Namespace URI is not exactly https://pagelove.org/Binding/Sessel |
Attributes are ignored — no bindings are created |
See also
- JavaScript expression binding — the JavaScript peer (
j:) - Resource Binding — CSS selector-based data binding (
r:) - Stamp — emit a bound value into the document as HTML with
<p:stamp> - Templating — using bound values in Liquid templates
- Sessel — the expression language used in bindings
- Method Elements — the general attribute-form dispatch mechanism
e:attributes use under the hood