Elements


content

Captures output contained within the content element to a text spool or local variable.

with name=""

Usage: <content name="x">anyXml</content>

Spools all output in the content element into a named text writer. The named content can be placed as output later with a <use/> element, or can be accessed directly with the Content["x"] dictionary.

with var="" or def=""

Usage: <content var="x">anyXml</content>

Usage: <content def="x">anyXml</content>

Spools all output into a temporary text writer, then assigns the results into a new string local variable named by the var attribute value.

with set=""

Usage: <content set="x">anyXml</content>

Usage: <content set="x" add="before|after|replace">anyXml</content>

Spools all output into a temporary text writer, then assigns the results into an existing local variable named by the set attribute value.

If the content element also contains add="after" the capured content will be appended to the end of the variable's existing value. If it contains add="before" the content will be appended to the front of the existing variable value.


def

An alias for declaring a local variable, see <var/>.


default

Declares local variables if a symbol of a given name is not known to be in scope.

Usage: <default x="a" y="b"/>

var x = a;
var y = b;

If a symbol x or y is known to exist in scope as a local variable, or declared viewdata or global property, the line declaring the variable will not be generated.

with type=""

Usage: <default x="a" y="b" type="t"/>

t x = a;
t y = b;


else

Forms a part of an if/elseif/else conditional structure.

Usage: <else>anyXml</else>

else
{
  //anyXml-generated-code
}

Must follow an element that produces an if/elseif statement. Contains material that will be rendered if all preceding conditions are false.

with if=""

Usage: <else if="x">anyXml</else>

else if(x)
{
  //anyXml-generated-code
}

Must follow an element that produces an if/elseif statement. Contains material that will be rendered if all preceding conditions are false, and the expression x evaluates to true.

empty element

Usage: <test if="x">anyXml-1<else if="y"/>anyXml-2<else/>anyXml-3</test>

if(x)
{
  //anyXml-1-generated-code
}
else if(y)
{
  //anyXml-2-generated-code
}
else 
{
  //anyXml-3-generated-code
}

Must be contained within an <if> or <test> element. The material following an empty <else/> element is treated as if it was contained within that element. If there are multiple <else/> elements all but the last one must have an if="" attribute.


elseif

Forms a part of an if/elseif/else conditional structure.

Usage: <elseif condition="x">anyXml</else>

else if(x)
{
  //anyXml-generated-code
}

Must follow an element that produces an if/elseif statement. Contains material that will be rendered if all preceding conditions are false, and the expression x evaluates to true.


for

Iterates over a collection

Usage: <for each="var x in y">anyXml</for>

foreach(var x in y)
{
  //anyXml-generated-code
}

If the generated code appears to reference symbols named xIndex, xCount, xIsFirst, or xIsLast the minimum number of local variables needed will also be generated using a pattern similar to the following.

{
  int xCount = util_count_of(y);
  int xIndex = 0;
  bool xIsFirst = true;
  foreach(var x in y)
  {
    bool xIsLast = (xIndex == xCount - 1);
    {
      //anyXml-generated-code
    }
    xIsFirst = false;
    xIndex++;
  }
}

with *="" assignments

Usage: <for each="var x in y" a="b" c="d">anyXml</for>

foreach(var x in y)
{
  a=b;
  c=d;
  //anyXml-generated-code
}


global

Declares a property that's available to all templates while rendering.

Usage: <global x="a" y="b" type="t"/>

object _x = a;
public object x {get {return _x;} set {_x = value;}}
 
object _y = b;
public object y {get {return _y;} set {_y = value;}}

Although object seems like an inconvenient type, it works quite well when used in simple value assignments like <set x="42"/> and expression output like ${x}.

with type=""

Usage: <global x="a" y="b" type="t"/>

t _x = a;
public t x {get {return _x;} set {_x = value;}}
 
t _y = b;
public t y {get {return _y;} set {_y = value;}}


if

Forms a part of an if/elseif/else conditional structure.

Usage: <if condition="x">anyXml</if>

if(x)
{
  //anyXml-generated-code
}

Material in an if element will only render if the condition evaluates to true.

Alias: <test if="">


include

TODO: forgot to write up this one


macro

Declares a member helper function available to all templates while rendering.

Usage: <macro name="anyName" x="t1" y="t2">anyXml</macro>

public string anyName(t1 x, t2 y)
{
  //anyXml-generated-code
}

Macros may be used invoked as part of an output expression ${anyName(a,b)} or anyplace else code appears like <set z="anyName(a,b)"/> or # z=anyName(a,b);


render

Within a partial file, renders the material wrapped by the reference to that partial file.

Usage: anyXml2<render/>anyXml4

Given: anyXml1<partialFileName>anyXml3</partialFileName>anyXml5

//anyXml1-generated-code
{
  //anyXml2-generated-code
  {
    //anyXml3-generated-code
  }
  //anyXml4-generated-code
}
//anyXml5-generated-code

When <render/> appears in a partial template it generates code for the contents of the element which referenced the partial. This can be used to have a partial file which "wraps" any sort of contained material in the parent template. This enabled partials to be used as content wrappers to produce rounded corners, ajax effects, around arbirtary content.

with segment="" (previously known as 'section')

Usage: anyXml2<render segment="anyName"/>anyXml4

Given: anyXml1<partialFileName><segment name="anyName">anyXml3</segment></partialFileName>anyXml5

//anyXml1-generated-code
{
  //anyXml2-generated-code
  {
    //anyXml3-generated-code
  }
  //anyXml4-generated-code
}
//anyXml5-generated-code

When <render segment=""/> appears in a partial template it renders the contents of the <segment name=""> contained in the referencing <render partial=""> template. This enables partials to render several distinct micro-templates, for example a repeater partial could have top/bottom/even/odd named segments.

See also: <segment/>

with *="" assignments

Usage: anyXml2<render x="a" y="b"/>anyXml4

Given: anyXml1<partialFileName>anyXml3</partialFileName>anyXml5

//anyXml1-generated-code
{
  //anyXml2-generated-code
  {
    var x = a;
    var y = b;
    //anyXml3-generated-code
  }
  //anyXml4-generated-code
}
//anyXml5-generated-code

Partial files may declare local variables when rendering passed in content. They are available to the scope of the wrapped content or named segment in the outer template file.

with fallback content

Usage: anyXml2<render segment="anyName" x="a" y="b">anyXml-fallback</render>anyXml4

Given: anyXml1<partialFileName/>anyXml5

//anyXml1-generated-code
{
  //anyXml2-generated-code
  {
    var x = a;
    var y = b;
    //anyXml-fallback-generated-code
  }
  //anyXml4-generated-code
}
//anyXml5-generated-code

When the reference to a partial file is empty, or the named segment does not exist, the contents of the <render> element in the partial file will generate the rendering code by default.

Given: anyXml1<partialFileName>anyXml3</partialFileName>anyXml5

//anyXml1-generated-code
{
  //anyXml2-generated-code
  {
    var x = a;
    var y = b;
    //anyXml3-generated-code
  }
  //anyXml4-generated-code
}
//anyXml5-generated-code

When the reference to a partial file has contents, the contents of the <render> element in the partial file is unused.


render partial=""

Includes the contents of a partial file for rendering at the point where it appears.

Usage: <render partial="_partialFileName"/>

Alias: <partialFileName/>

{
  //_partialFileName.spark-generated-code
}

Partial files may have any name, but usually start with _ by convention. The name without the underscore may be used as a short version of the <render/> element.

with *="" assignments

Usage: <render partial="_partialFileName" x="a" y="b"/>

{
  var x = a;
  var y = b;
  //_partialFileName.spark-generated-code
}

A partial file reference may declare local variables. They are available to the scope of the wrapped content or named segment.


segment (previously known as 'section')

Declares a segment of material passed in to a partial file reference.

Usage: anyXml1<partialFileName><segment name="anyName">anyXml3</segment></partialFileName>anyXml5

Given: anyXml2<render segment="anyName"/>anyXml4

//anyXml1-generated-code
{
  //anyXml2-generated-code
  {
    //anyXml3-generated-code
  }
  //anyXml4-generated-code
}
//anyXml5-generated-code

When <render segment=""/> appears in a partial template it renders the contents of the <segment name=""> contained in the referencing <render partial=""> template. This enables partials to render several distinct micro-templates, for example a repeater partial could have top/bottom/even/odd named segments.

with *="" assignments

Usage: anyXml1<partialFileName><segment name="anyName" x="a" y="b">anyXml3</segment></partialFileName>anyXml5

Given: anyXml2<render segment="anyName"/>anyXml4

//anyXml1-generated-code
{
  //anyXml2-generated-code
  {
    var x = a;
    var y = b;
    //anyXml3-generated-code
  }
  //anyXml4-generated-code
}
//anyXml5-generated-code


set

Assigns an expression to a variable.

Usage:

x = a;
y = b;

This is arguably the least interesting element in the entire Spark library. But if it wasn't there you'd probably have to escape assignments into code fragments like #x = a;. So there you go.


test

Forms a part of an if/elseif/else conditional structure.

Usage: <test if="x">anyXml</test>

if(x)
{
  //anyXml-generated-code
}

Material in a test element will only render if the condition evaluates to true.

Alias: <if condition="">


use assembly=""

Ensures a partially or fully qualified assembly name is include when the Spark assembly is compiled.

Usage: <use assembly="system.something.something"/>

Usage: <use assembly="system.something.something, etc=20394824, etc=239483432"/>


use content=""

Renders whatever has been captured in a named content spool.

Usage: <use content="x"/>

if (Contents.ContainsKey("x"))
{
  Output.Write(Contents["x"]);
}

The use of content spooling is actually very efficient. It uses pooled pages of string references to replay the original output, which doesn't increase memory pressure and avoids string copying and concatination costs.

There is a built-in content spool named "view".

with fallback content

Usage: <use content="x">anyXml-fallback</use>

if (Contents.ContainsKey("x"))
{
  Output.Write(Contents["x"]);
}
else
{
  // anyXml-fallback-generated-code
}

If the named content segment has never been written into the fallback output is generated. This can be used for default title contents, for example <title><use content="title">My Default Title</use></content>, or for wrapping any html in the layout you may want to entirely replace in some views.


use file=""

An alias for <render partial=""/>.

Usage: <use file="_partialFileName"/>

All behavior is identical to render partial.


use import=""

Includes all of the elements which have a global effect declared in a template.

Usage: <use import="fileName"/>

This can be used to organize elements like <viewdata/>, <global/>, <macro/>, <use import=""/>, <use assembly=""/>, <use namespace=""/> into importable template files for greater manageability.

The well-known file named _global.spark in the current template's directory, and in the Shared directory, is automatically imported.


use master=""

Forces the layout around the current template file to become the named file.

Usage: <use master="fileName"/>

This will override the master which would normally have been used. Multi-level rendering can be accomplished by chaining templates with use master="" elements.

This element has no effect when it's in a partial file or import file.


use namespace=""

Uses a dotnet namespace in the generated code.

Usage: <use namespace="any.name.space"/>

using any.name.space;

Uses a namespace. Frequently placed in an import file like _global.spark.


var

Declares a local variables and it's initialization expression.

Usage: <var x="a" y="b"/>

var x = a;
var y = b;

with type=""

Usage: <var x="a" y="b" type="t"/>

t x = a;
t y = b;


viewdata

Declares an accessor property for a piece of view data.

Usage: <viewdata x="t1" y="t2" />

public t1 x { get { return (t1)ViewData.Eval("x"); } }
public t2 y { get { return (t2)ViewData.Eval("y"); } }

with default=""

Usage: <viewdata x="t1" y="t2" default="d"/>

public t1 x { get { return (t1)(ViewData.Eval("x") ?? d); } }
public t2 y { get { return (t2)(ViewData.Eval("y") ?? d); } }

Adds a fallback value for the property in cases where the actual view data is missing or null.

with property name

Usage: <viewdata x="t1 anyName1" y="t2 anyName2" />

public t1 anyName1 { get { return (t1)ViewData.Eval("x"); } }
public t2 anyName2 { get { return (t2)ViewData.Eval("y"); } }

A name following the type will determine the name of the property which is added. This enables you to declare viewdata accessors which contain dashes or dots, which are not allowed in property names.


viewdata model=""

Provides a generic parameter to strongly type the Model of the view's base class.

Usage: <viewdata model="t1" />

public class generated_view_name : base_view_name<t1>
{
  public t1 Model { get { return ViewData.Model; } }
}

The base view class is strongly typed, and a typed property named Model is added to the generated view.

with property name

Usage: <viewdata model="t1 anyName" />

public class generated_view_name : base_view_name<t1>
{
  public t1 Model { get { return ViewData.Model; } }
  public t1 anyName { get { return ViewData.Model; } }
}

A name following the type causes an additional property of that name to be added as an alias for the Model property.


See also: source code

The above is based on code in the following files.

ChunkBuilderVisitor.cs

GeneratedCodeVisitor.cs