Symple 2.1.1

dotnet add package Symple --version 2.1.1
                    
NuGet\Install-Package Symple -Version 2.1.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Symple" Version="2.1.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Symple" Version="2.1.1" />
                    
Directory.Packages.props
<PackageReference Include="Symple" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Symple --version 2.1.1
                    
#r "nuget: Symple, 2.1.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Symple@2.1.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Symple&version=2.1.1
                    
Install as a Cake Addin
#tool nuget:?package=Symple&version=2.1.1
                    
Install as a Cake Tool

Symple

A simple templating engine for .NET Standard 2.0.

Example

var template = "$person.Name's father was $person.Father.Name.";

var variables = new Dictionary<string, object>
{
    ["person"] = new
    {
        Name = "Stephen",
        Father = new { Name = "Frank" }
    }
};

var output = Symple.Parser
    .Parse(template)
    .Render(variables);

// Output: "Stephen's father was Frank."

Advanced example

var template = @"
<h1>Planets</h1>
<ul>@[$planet:$planets] {
    <li>
        <h2>$planet.Name</h2>?[$planet.Moons] {
        <strong>$planet.Name has #$planet.Moons moon?[#$planet.Moons!=1]{s}</strong>
        <ul>@[$moon:$planet.Moons] {
            <li>$moon</li>}
        </ul>} {
        <strong>$planet.Name has no moons</strong>}
    </li>}
</ul>";

var variables = new Dictionary<string, object>
{
    ["planets"] = new[]
    {
        new { Name = "Earth", Moons = new[] { "Moon" } },
        new { Name = "Mars", Moons = new[] { "Phobos", "Deimos" } },
        new { Name = "Venus", Moons = new string[0] { /* Venus has no moons */ } }
    },
};

var output = Symple.Parser
    .Parse(template)
    .Render(variables);

// Output:
// <h1>Planets</h1>
// <ul>
//     <li>
//         <h2>Earth</h2>
//         <strong>Earth has 1 moon</strong>
//         <ul>
//             <li>Moon</li>
//         </ul>
//     </li>
//     <li>
//         <h2>Mars</h2>
//         <strong>Mars has 2 moons</strong>
//         <ul>
//             <li>Phobos</li>
//             <li>Deimos</li>
//         </ul>
//     </li>
//     <li>
//         <h2>Venus</h2>
//         <strong>Venus has no moons</strong>
//     </li>
// </ul>

Syntax

  • Variables
    • $var or $[var]
    • $var.a.b.c for nested objects.
  • Conditionals
    • ?[condition] {if} {else}
    • or without the else
    • ?[condition] {if}
  • Loops
    • @[$x:$xs] {use $x here}
    • Variable $xs must implement IEnumerable, i.e. pretty much every .NET collection class will work.
  • Logical operators - operands are evaluated as bool.
    • !     Logical NOT
    • &&   Logical AND
    • ||   Logical OR
  • Comparison operators - operands are evaluated as decimal
    • <     Less than
    • >     Greater than
    • <=   Less than or equal
    • >=   Greater than or equal
    • Note if any expression that is not a numeric is part of the comparision it will yield false.
  • Equality operators - operands are evaluated as string.
    • ==   Equal
    • !=   Not Equal
  • Grouping in a condition to override default operator precedence
    • e.g. ?[$a && ($b || $c)]
  • Collection count
    • ?[#$items == 1]{exactly 1 item}
      • Evaluates to the length of the IEnumerable variable as an integer.
      • If the variable is not an IEnumerable will evaluate to "" / false.

Types

The core types used in Symple are string for rendering, bool for conditionals and decimal for any numeric comparisons. You can pass any .NET type as a variable to the template but keep in mind when rendering a variable Symple will call .ToString() on it so using anything other than a string as the final expression can lead to unwanted output. For example, an int[] variable would be rendered as System.Int32[] which is unlikely what you want.

Implicit bool conversion

Any expression can be used directly in the conditional expression, e.g. ?[$var] { ... } is valid syntax for any variable. For any type other than bool we will convert the expression's value to a bool by these rules:

  • null: false
  • string s: s.Length > 0
  • IEnumerable e: e.Any()
  • Any other value v with type T: !v.Equals(default(T)).
    • Any numeric type (int / float etc) is true when not 0.
    • char is true when not \0.
    • Any reference type is true when not null.

Conditional expression

The conditional expression ?[condition] {if} {else} allows the following expressions as condition, where any expression other than bool will be implicitly converted to bool.

  • Variables
    • ?[$x]
    • See in "Implicit bool conversion" how variables are converted to bool.
  • Strings
    • ?["str"]
    • ?[$a == "str with $var"]
    • Note unlike in the template itself it requires " delimiters.
    • A string evaluates to true unless empty ("").
  • Numbers
    • ?[1]
    • ?[2.5 > 2]
    • Numbers evaluate to true unless equal to 0.
  • Logical expressions (!, &&, || and parentheses)
    • ?[$a && $b]
    • ?[!$a]
    • ?[!$a && ($b || $c)]
    • Note, this evaluates operands as bool
  • Comparison (<, >, <=, >=)
    • ?[$a > $b && $a < 2]
    • ?[$a <= 1.5 || $a >= 4]
    • Note, this evaluates operands as decimal
  • Equality (==, !=)
    • ?[$a == "value"]
    • ?[$b != "other"]
    • Note, this evaluates operands as string
  • Collection count operator
    • ?[#$items > 1]
  • Nested conditionals
    • ?[?[$a]{$b}{$c}]
      • This condition evaluates $b if $a is true, otherwise $c.
      • Based on $b or $c the if or else branch of the original conditional is executed.
    • Possible, though potentially confusing

All the above expressions can be infinitely combined using the various operators.

Escaping special characters

Symple defines the following special characters:

  • $
  • ?
  • @
  • #
  • "
  • }
  • \

Any character can be escaped using \, even if it is not a special character. For example, the template H\ello\, \World\! will result in Hello, World!.

However, there is generally no need to escape the special characters in a template. The exception is the escape character \, which always escapes the next character thus always needs to be escaped itself. That is, to render C:\Windows the template needs to be C:\\Windows.

Because Symple uses 2 or more characters for most of its syntax there is no need to escape any of the other special characters when they appear by themselves except " (only inside a condition) and } (only inside an if/else/loop branch).

For example, the Symple parser understands that name@example.com is not a loop expression, just like $100 cannot be a variable because 100 is not a valid identifier. Likewise, using a ? in a sentence or using #hashtag is not a problem.

The only things you actually need to escape are these sequences if you want them to render as-is without being considered Symple syntax:

  • \ → \\

    • As mentioned above the escape character \ always needs to be escaped
  • $var → \$var

    • $ followed by a letter or _ must be escaped to not be considered a variable
  • ?[ → \?[

    • ?[ must be escaped to not be considered a conditional expression
  • @[ → \@[

    • @[ must be escaped to not be considered a loop expression
  • #$var → \#$var

    • # followed by a valid variable needs to be escaped to not be considered a collection count expression
  • ?["str with "quotes""] → ?["str with \"quotes\""]

    • A string inside a condition needs to escape ".
  • ?[1] { use } in here } → ?[1] { use \} in here }

    • } inside an if or else branch needs to be escaped
    • Similarly in a loop, i.e. @[..]{ in here }.

You can use Parser.Escape(string input) to escape special characters.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETStandard 2.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.1.1 214 5/29/2025
2.1.0 225 8/18/2024
2.0.0 191 8/10/2024
1.0.1 199 5/5/2024
1.0.0 193 4/10/2024