Reactive Logic - PageAmp/pageamp GitHub Wiki
Attributes prefixed with :
are trated as logic attributes. They don't appear in generated HTML and can be used in logic expressions.
When their value change, all dependent expressions are re-evaluated and the page is automatically updated.
For example, this source page:
<html>
<head :bgColor="#fff">
<style>
body {
background-color: [[bgColor]];
}
</style>
</head>
</html>
will generate this code:
<html>
<head>
<style>
body {
background-color: #fff;
}
</style>
</head>
</html>
Logic attributes prefixed with :class-
, :style-
, :on-
and :event-
have special behaviours.
In addition to using the standard class
attribute, CSS classes can be dynamically added and removed with the :class-
attributes.
For example, this DIV:
<div class="box" :class-red=[[alarm]] :alarm=[[false]]></div>
will have class="box red"
or class="box"
depending on :alarm
being true or false.
In addition to using the standard style
attribute, CSS styles can be dynamically set with the :style-
attributes.
For example, this DIV:
<div class="box"
:style-background=[[alarm ? 'red' : null]]
:alarm=[[false]]></div>
will have style="background: red"
or no style
at all depending on :alarm
being true or false.
Attributes prefixed with :on-<name>
define expressions that are evaluated whenever the <name>
attribute changes value.
For example this code:
<body :count=[[0]]
:on-count=[[delayedSet('count', count + 1, 1)]]>
Seconds: [[count]]
</body>
implements a seconds counter. Here are the details:
- Server-side,
count
is assigned to zero. The handler is called just like in the client, but it uses thedelayedSet()
function with a 1 second delay, so it has no effect on the output page. - Client-side the page is initially displayed as it arrived, with the "Seconds: 0" text. As soon as the client runtime starts, it repeats what the server did in the server. This time, the
delayedSet()
does work andcount
is incremented after the delay elapses. This in turn re-evaluates the handler expression and so on.
Attributes prefixed with :event-<type>
declare client-side event handlers associated to an element.
For example this code:
<body :count=[[0]] :event-click=[[count++]]>
Clicks count: [[count]]
</body>
will initially display "Clicks count: 0" and will then change at each user click.
:data
is a reserved attribute name, used to give an element a `data context.
:aka
is a reserved attribute name, used to give a logic name to page elements.
You can inject expressions surounded with [[
and ]]
anywhere in page text and attribute values. They can access logic attributes, implement complex behaviour, and their resulting value is automatically applied to the page.
Expressions are reactive. This means that they are automatically re-evaluated, and re-applied to the page, when the logic attributes they refer to change value.
In this example:
<html>
<body :count=[[0]]
:on-count=[[delayedSet('count', count + 1, 1)]]>
Seconds: [[count]]
</body>
</html>
the body text expression gets updated and re-applied to the page each time :count
changes value.
TBD
PageAmp doesn't treat HTML as plain text, like a templating engine would do. Both in the server and in the client, HTML is parsed into an actual DOM before page logic is executed.
Expressions can see logic attributes defined in their own element as well as in all its parent nodes.
For example:
<html>
<head :bgColor="$fff">
<style>
body {
background-color: [[bgColor]];
}
</style>
</head>
<body>
<!--
expressions here cannot directly see "bgColor"
-->
</body>
</html>
Elements, though, can be given a logic name with :aka
:
<html>
<head :aka="head" :bgColor="$fff">
<style>
body {
background-color: [[bgColor]];
}
</style>
</head>
<body>
<!--
expressions here can see "head" so they can
indirectly access "bgColor" through it
-->
[[head.bgColor]]
</body>
</html>
Actually, the :aka
attribute above is redundant: elements <html>
, <head>
and <body>
are always implicitly given the names "page", "head" and "body", respectively.
:aka
was chosen over:name
because the latter is often a desirable name for a logical attribute.