JY66.SimpleTemplateEngine 1.1.0

dotnet add package JY66.SimpleTemplateEngine --version 1.1.0
                    
NuGet\Install-Package JY66.SimpleTemplateEngine -Version 1.1.0
                    
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="JY66.SimpleTemplateEngine" Version="1.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="JY66.SimpleTemplateEngine" Version="1.1.0" />
                    
Directory.Packages.props
<PackageReference Include="JY66.SimpleTemplateEngine" />
                    
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 JY66.SimpleTemplateEngine --version 1.1.0
                    
#r "nuget: JY66.SimpleTemplateEngine, 1.1.0"
                    
#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 JY66.SimpleTemplateEngine@1.1.0
                    
#: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=JY66.SimpleTemplateEngine&version=1.1.0
                    
Install as a Cake Addin
#tool nuget:?package=JY66.SimpleTemplateEngine&version=1.1.0
                    
Install as a Cake Tool

SimpleTemplateEngine

A lightweight, dependency-free C# templating engine that turns plain objects into formatted text.
Designed for email bodies, subjects, notifications, and any scenario where you want to build text
from simple models without pulling in heavy template engines.

✔ Attribute-based
✔ Zero runtime dependencies
✔ Plug-in template sources (JSON, configuration, DB, files, etc.)
✔ Recursive list rendering
✔ Safe, straightforward, reflection-based field & property substitution


📦 Installation

Using .NET CLI

dotnet add package JY66.SimpleTemplateEngine
dotnet add package JY66.SimpleTemplateEngine.Adapters.Configuration

🚀 Quick Start

1. Define a model and attach a template key

using JY66.SimpleTemplateEngine;

[Template("Emails:Welcome:Body")]
public class WelcomeEmailModel
{
    public string FirstName { get; set; }
    public DateTime SignupDate { get; set; }
}

2. Provide a template source

If using IConfiguration, the library includes an adapter:

var config = new ConfigurationBuilder()
    .AddJsonFile("appsettings.json")
    .Build();

var source = new ConfigurationTemplateSource(config);

3. Render the template

var model = new WelcomeEmailModel
{
    FirstName = "Josh",
    SignupDate = DateTime.UtcNow
};

string result = TemplateRenderer.Render(model, source);
Console.WriteLine(result);

4. Add the template to configuration

"Emails": {
  "Welcome": {
    "Body": "Hi ||FirstName||, thanks for signing up on ||SignupDate||!"
  }
}

Output:

Hi Josh, thanks for signing up on 11/26/2025 4:15 PM!

🧩 Placeholder Rules

Scalar placeholders match public properties or public fields on your model:

||PropertyName||

Example:

public string AuthorizationCode { get; set; }

Template:

Your code is: ||AuthorizationCode||

For nested objects or lists of objects that have their own [Template], use the member name wrapped in double asterisks:

**MemberName**
  • If MemberName is a single object, its template is rendered once and inserted.
  • If MemberName is a List<T>, each item is rendered with the template for T and concatenated in place.
  • If the member type lacks a [Template] attribute, rendering throws an exception noting the member name.
  • Circular template references are detected and result in a descriptive exception to prevent infinite loops.

🧮 Built-in & Inline Formatting

You can control formatting directly inside placeholders using the syntax:

||MemberName:FormatString||

Examples:

||Amount:c2||          → $1,234.56
||InvoiceDate:yyyy-MM-dd|| → 2024-11-26

If no inline format string is supplied, the engine falls back to sensible defaults:

Type Default Output Format
decimal Currency ($1,234.56)
DateTime MM/dd/yyyy h:mm tt
Others ToString()

📚 Nested Rendering (Objects & Lists)

Embed the **member name** of your child object inside the parent template:

**MemberName**

Example

Models
[Template("Orders:Summary")]
public class OrderSummary
{
    public string CustomerName { get; set; }
    public Address ShippingAddress { get; set; }
    public List<OrderLine> Lines { get; set; } = new();
}

[Template("Orders:Address")]
public class Address
{
    public string Street { get; set; }
    public string City { get; set; }
}

[Template("Orders:Line")]
public class OrderLine
{
    public string Description { get; set; }
    public decimal Amount { get; set; }
}
Templates
"Orders": {
  "Summary": "Order for ||CustomerName||:\nShip To:\n**ShippingAddress**\nItems:\n**Lines**",
  "Address": "||Street||, ||City||\n",
  "Line": "- ||Description||: ||Amount||\n"
}

Output:

Order for Josh:
Ship To:
123 Main St, Austin
Items:
- Widget A: $12.95
- Widget B: $49.00

🔌 Providing Your Own Template Source

The engine works with any backing store:

  • Database
  • Filesystem
  • Embedded resources
  • Remote config
  • Your own dictionary

Create your own provider:

public class DictionaryTemplateSource : ITemplateSource
{
    private readonly Dictionary<string,string> _templates;

    public DictionaryTemplateSource(Dictionary<string,string> templates)
        => _templates = templates;

    public string GetTemplate(string key) => _templates[key];
}

Then use it:

var source = new DictionaryTemplateSource(new()
{
    ["Test"] = "Hello ||Name||"
});

🧪 Unit Testing

Inject a dictionary-based template source during tests:

var src = new DictionaryTemplateSource(new()
{
    ["MyTemplate"] = "Value: ||Field||"
});

🏗 Project Goals

  • Provide a simple, predictable templating engine for lightweight scenarios.
  • Avoid the complexity of Razor, Scriban, Fluid, etc.
  • Keep the API clean, small, and dependency-free.
  • Work in console apps, background services, serverless functions, and microservices.

🔮 Roadmap

  • Basic conditionals
  • Template caching
  • File-based template provider

📄 License

MIT License — free for personal and commercial use.


🤝 Contributing

Pull requests are welcome!

  • Add tests
  • Improve docs
  • Add template sources
  • Expand formatting or features

⭐ Support

If you find this useful, consider starring the repo on GitHub!

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 netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen 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.1

    • No dependencies.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on JY66.SimpleTemplateEngine:

Package Downloads
JY66.SimpleTemplateEngine.Adapters.Configuration

A lightweight templating engine for .NET.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.1.0 154 12/29/2025
1.0.3 707 12/3/2025
1.0.1 463 11/30/2025
1.0.0 200 11/27/2025