Variable Assignment

So far, we’ve been working with data that we’ve pushed into a Context using Scopes or the Model. However, we can define variables directly in the template itself using assign. These values are pushed into the Scope for whichever template on which they appear.

{% assign name = "Deane" %}

Once pushed into a Scope, the variable can be output just like data from the Context.

My name is {{ name }}.

You can use the variable as a filter argument.

{% assign name = "Deane" %}
{% assign volume = 10 %}
My name is {{ name | exclaim: volume  }}

You can assign a variable to another variable, even one that’s filtered:

{% assign name = "Deane" %}
{% assign volume = 3 %}
{% assign yell = name | exclaim: volume %}
My name is {{ yell }}

You can assign the result of a filter call when the returned value is an ObjectValue.

TemplateOptions.Default.Filters.AddFilter("get_person", (i, a, c) =>{
  return new ObjectValue(new { Name = i });  
});
{% assign person = "Deane" | get_person %}
My name is {{ person.Name }}.

You can assign entire blocks of output to variables by enclosing other statements and content with an capture tag which includes the name of the variable to which to assign the output.

{% capture body %}
  All sorts of stuff here, including logic and a mix of tags, blocks, and text.
{% endcapture %}

After that block executes, the body variable will contain everything between the capture and endcapture tags, post-execution (meaning after all logic has executed).

You can use this for a quick “layouts” feature:

{% capture title %}My Title{% endcapture %}
{% capture body %}
    <p>This is the body.</p>
{% endcapture %}
{% include 'layout' %}
<html>
  <head>
    <title>{{ title }}</title>
  </head>
  <body>
    <h1>{{ title }}</h1>
    {{ body }}
  </body>
</html>

There’s a C# delegate method that executes when capture completes. It will pass the name of the variable and the output of the block to a method you can supply. The use cases are on the edge, but it could come in handy.

For example, you could capture multiple outputs from one template.

var results = new Dictionary<string,string>();
context.Captured = (n, v) =>
{
  results[n] = v;
  return new ValueTask<string>();
};
{% capture deane %}My name is Deane.{% endcapture %}
{% capture annie %}My name is Annie.{% endcapture %}

Nothing will output from this, as everything is captured in variables which are never output. But the results dictionary will now look like this:

["deane"] = "My name is Deane."
["annie"] = "My name is Annie."