Examples of custom Chloe tags
Furnace framework » Furnace presentation layer » Chloe templates » Extending Chloe » Extending Chloe with custom tags

Prev:compile-with-scope ( quot -- )

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 ;