Variables in SXML: buffers

Release 1.0 - ...

Every programming language needs a concept of variables that can be declared, written and read.

In SXML, these variables are named 'buffers', and they can be declared implicitly:

Smartsite SXML CopyCode image Copy Code
<se:text save="x">
   Hello world!
</se:text>

or explicitly:

Smartsite SXML CopyCode image Copy Code
{buffer.set(x, 'Hello world!'}

Values of any SXML data type can be stored in buffers:

Smartsite SXML CopyCode image Copy Code
{buffer.set(eventdate, datetime.getdate('2008-10-01'))}
Smartsite SXML CopyCode image Copy Code
<se:xlinks resulttype="datatable" save="mylist" />

Using buffers

Saved buffers can be used in macro parameters explicitly requesting a savebuffer name:

Smartsite SXML CopyCode image Copy Code
<se:buffer name="myvar" />

or using the Viper syntax:

Smartsite SXML CopyCode image Copy Code
{buffer.get(myvar)}

When using buffers in Viper expressions, you can shortcut calls like this:

Smartsite SXML CopyCode image Copy Code
{string.trim(buffer.get(s))}

as follows:

Smartsite SXML CopyCode image Copy Code
{string.trim($s)}

Buffer names

SaveBuffer names are validated according to the following pattern:

  • First chraracter: 'a'-'z', 'A'-'Z'
  • Rest: 'a'-'z', 'A'-'Z', '0'-'9', '-', '_', '.'

Examples

Smartsite SXML CopyCode image Copy Code
{buffer.set(a01, 'Foo')} ==> ok
{buffer.set('B.2', 'Foo')} ==> ok
{buffer.set('C_3', 'Foo')} ==> ok
{buffer.set('D-4', 'Foo')} ==> ok
{buffer.set('E_5', 'Foo')} ==> ok
{buffer.set(1st, 'Foo')} ==> error
{buffer.set('2nd', 'Foo')} ==> error
{buffer.set('.test', 'Foo')} ==> error

Buffer scope

Once declared, buffers have a well-defined lifetime.

Region

Within the boundaries of a region macro, buffer scope will be constrained to the region unless explicitly declared otherwise.

Smartsite SXML CopyCode image Copy Code
<!-- declare local scope -->
<se:region>
{buffer.set(x, page, 'Hello world!')}
</se:region>

Field

This is the default scope, meaning that code outside the field cannot read to the same variables. The only exception being the logic and body fields, which are seen as a single scope.

Page

Page scope variables are valid during the entire rendering of a page. Page scope must be explicitly declared.

Smartsite SXML CopyCode image Copy Code
{buffer.set(x, page, 'Hello world!')} <!-- create page scope buffer 'x' -->
Smartsite SXML CopyCode image Copy Code
{buffer.get(x, page)} <!-- use page scope buffer 'x' -->
Smartsite SXML CopyCode image Copy Code
<se:text save="page:myvar"> <!-- creste page scope buffer 'myvar' -->
   [your sxml]
</se:text>
Smartsite SXML CopyCode image Copy Code
<se:buffer name="myvar" /> <!-- use page scope buffer 'myvar' -->

Notes
If you want to share variables between rendertemplates, translations and items, you must now declare the buffers with explicit scoping to 'Page'.

Macro results and buffers

Macro results can be saved using the 'save' parameter.

Smartsite SXML CopyCode image Copy Code
<se:text save="a">Hello world</se:text>

This macro will store the 'Hello world' string in a buffer and the macro result itself will be cleared.

However, the save parameter is in fact a collection, built up as name = ViperExpression pairs. For example:

Smartsite SXML CopyCode image Copy Code
<se:text save="a = this.result()">Hello world</se:text>

Now, something interesting is happening here: when using this syntax, the macro' s result is not cleared!

In fact, the macro result is only cleared when only one entry exists in the collection and the expression holds a single variable name. The save="string" notation is in fact a denormalization for compatibility. To clear the result when using the formal syntax, use resulttype="none":

Smartsite SXML CopyCode image Copy Code
<se:text save="a = this.result()" resulttype="none">Hello world</se:text>

You can play with this to get the right results:

Smartsite SXML CopyCode image Copy Code
<se:xlinks save="a"/>

Clears result, saves formatted HTML.

Smartsite SXML CopyCode image Copy Code
<se:xlinks save="a = this.result(datatable)"/>

Does not clear result, saves the datatable internediate result for later use, displays formatted HTML.

Smartsite SXML CopyCode image Copy Code
<se:xlinks save="a = this.result(datatable)" resulttype="none"/>

Clears the result, saves the intermediate datatable result for later use.