As a first example, let's develop a custom Chloe tag which simply renders a random number. The tag will be used as follows:
<t:random t:min='10' t:max='20' t:generator='system' />
The
t:min and
t:max parameters are required, and
t:generator, which can equal one of
default,
system or
secure, is optional, with the default being
default.
Here is the
USING: form that we need for the below code to work:
USING: combinators kernel math.parser ranges random
html.templates.chloe.compiler html.templates.chloe.syntax ;
We write a word which extracts the relevant attributes from an XML tag:
: random-attrs ( tag -- min max generator )
[ "min" required-attr string>number ]
[ "max" required-attr string>number ]
[ "generator" optional-attr ]
tri ;
Next, we convert a random generator name into a random generator object:
: string>random-generator ( string -- generator )
{
{ "default" [ random-generator ] }
{ "system" [ system-random-generator ] }
{ "secure" [ secure-random-generator ] }
} case ;
Finally, we can write our Chloe tag:
CHLOE: random
random-attrs string>random-generator
'[
_ _ _
[ [a..b] random present write ]
with-random-generator
] [code] ;
For the second example, let's develop a Chloe tag which repeatedly renders its child several times, where the number comes from a form value. The tag will be used as follows:
<t:repeat t:times='n'>Hello world.<br /></t:repeat>
This time, we cannot simply extract the
t:times attribute at compile time since its value cannot be determined then. Instead, we execute
compile-attr to generate code which pushes the value of that attribute on the stack. We then use
process-children to compile child elements as a nested quotation which we apply
times to.
CHLOE: repeat
[ "times" required-attr compile-attr ]
[ [ times ] process-children ]
bi ;