Macros

Neotonic ClearSilver also supports the concept of macros. There are two commands for this support, def which defines the macro, and call which issues the call. Here is an example macro definition. This macro takes the value of one variable, and walks a part of the dataset to expand that value into a string value.

<?cs def:map_val(val, map) ?>
  <?cs each:item = map ?>
    <?cs if:val == item ?>
      <?cs var:item.val ?>
    <?cs /if ?>
  <?cs /each ?>
<?cs /def ?>
You might call this with the following dataset:
Lang.Dates {
  Weekdays {
    0 = 0
    0.val = Sunday
    1 = 1
    1.val = Monday
    2 = 2
    2.val = Tuesday
    3 = 3
    3.val = Wednesday
    4 = 4
    4.val = Thursday
    5 = 5
    5.val = Friday
    6 = 6
    6.val = Saturday
  }
}
<?cs call:map_val(#6, Lang.Dates.Weekdays) ?>
This will result in the output of "Saturday". Note that in reality, the output is going to contain a lot of whitespace. This is a common side-effect of each iteration. This is template substitution, all of the whitespace you see outside CS tags will actually be passed on to the output stream, and that includes once for every iteration through the loop. For that reason, you might want to define the map_val function without the whitespace. One way of doing that is to create one big long line with all the tags right next to eachother. However, because whitespace inside of template tags is not passed on, you can hide whitespace within the tags, or within comment tags.

<?cs def:map_val(val, map) ?><?cs each:item = map 
    ?><?cs if:val == item 
      ?><?cs var:item.val ?><?cs 
      /if ?><?cs 
    /each ?><?cs 
/def ?>

You can also see from this example, that macro arguments can be any of the four types of arguments. Currently, if you were to pass a string or numeric value as the item parameter, ie a parameter which is expected to be a part of the dataset, weird things will happen. In some cases, it will always evaluate to the value, ie if you pass item as "wow", and ask for item.foo, you'll get "wow". If you ask for the children of item, it will think you are crazy, and instead assume that you meant item as a global variable, and look it up in the dataset under that name.