A powerful and extensible template engine for .NET with built-in Scriban support, designed for code generation and file templating in the NFramework ecosystem.
- Scriban Integration: Fast and powerful Scriban template engine
- Template Rendering: Support for string templates and file templates
- Batch Processing: Efficient rendering of multiple files at once
- Built-in Functions: Custom string manipulation functions (CamelCase, PascalCase, SnakeCase, KebabCase, etc.)
- Dependency Injection: Ready-to-use extension methods
- Clean Architecture: Strict separation between abstractions and implementations
NFramework.Core.Template.Abstractions- Core interfaces and abstractionsNFramework.Core.Template.Engine- Core template engine implementationNFramework.Core.Template.Scriban- Scriban-based template renderer with custom functions
dotnet add package NFramework.Core.Template.Abstractions
dotnet add package NFramework.Core.Template.Engine
dotnet add package NFramework.Core.Template.Scribanusing Microsoft.Extensions.DependencyInjection;
using NFramework.Core.Template.Abstractions;
using NFramework.Core.Template.Scriban;
using NFramework.Core.Template.Engine.DependencyInjection;
// Add to DI container
var services = new ServiceCollection();
services.AddScribanTemplateEngine();Create simple template data classes:
public record MyTemplateData(
string ProjectName,
string Namespace,
bool IncludeApi
);var data = new MyTemplateData(
ProjectName: "MyAwesomeApp",
Namespace: "MyApp.Domain",
IncludeApi: true
);
string template = @"
namespace {{ Namespace }}
{
public class Project
{
public string Name { get; set; } = ""{{ ProjectName }}"";
public bool HasApi = {{ IncludeApi }};
}
}
";
var renderer = serviceProvider.GetRequiredService<ITemplateRenderer>();
string result = await renderer.RenderAsync(template, data);
// Result: Generated C# class with proper values// Create a template file at templates/Project.cs.sbn
// Render it to output directory
var request = new Models.TemplateFileRenderRequest(
TemplateFilePath: "templates/Project.cs.sbn",
TemplateDirectoryPath: "templates",
OutputDirectoryPath: "output",
PathVariableReplacements: new Dictionary<string, string>
{
{ "{{region}}", "Demo" }
},
Data: data
);
var engine = serviceProvider.GetRequiredService<ITemplateEngine>();
string outputPath = await engine.RenderFileAsync(request);var batchRequest = new Models.TemplateFilesRenderRequest(
TemplateFilePaths: new[]
{
"templates/Project.cs.sbn",
"tests/ProjectTests.cs.sbn"
},
TemplateDirectoryPath: "templates",
OutputDirectoryPath: "output",
PathVariableReplacements: new Dictionary<string, string>(),
Data: data
);
IReadOnlyList<string> outputPaths = await engine.RenderFilesAsync(batchRequest);The template engine provides additional string manipulation functions:
// Input: "UserEntity"
// Functions:
- {{ UserEntity | string.camel_case }} // "userEntity"
- {{ UserEntity | string.pascal_case }} // "UserEntity"
- {{ UserEntity | string.snake_case }} // "user_entity"
- {{ UserEntity | string.kebab_case }} // "user-entity"
- {{ UserEntity | string.abbreviation }} // "ue"
- {{ UserEntity | string.plural }} // "UserEntities"
- {{ UserEntity | string.singular }} // "UserEntity"
- {{ UserEntity | string.words }} // "User Entity"public record ComplexTemplateData
{
public string Name { get; set; }
public List<Entity> Entities { get; set; }
public Config Config { get; set; }
public record Entity(string Name, List<string> Properties);
public record Config(bool EnableAuth, string DatabaseProvider);
}// Path: "src/{{ProjectName}}/Models/{{EntityName}}.cs"
// Data: ProjectName = "MyApp", EntityName = "User"
// Result: "src/MyApp/Models/User.cs"
var pathRequest = new Models.TemplateFileRenderRequest(
TemplateFilePath: "templates/{{ProjectName}}/Models/{{EntityName}}.cs.sbn",
TemplateDirectoryPath: "templates",
OutputDirectoryPath: "src/{{ProjectName}}",
PathVariableReplacements: new Dictionary<string, string>(),
Data: new { ProjectName = "MyApp", EntityName = "User" }
);try
{
string result = await renderer.RenderAsync(template, data);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("Template parse failed"))
{
// Handle template parsing errors
Console.WriteLine($"Template error: {ex.Message}");
}
catch (Exception ex)
{
// Handle other errors
Console.WriteLine($"Error: {ex.Message}");
}ITemplateEngine- Main orchestration interfaceITemplateRenderer- Core template rendering interfaceITemplateData- Template data provider interface- Request/Response types - Strongly typed request objects
NFrameworkTemplateEngine- File system operations and batchingScribanTemplateRenderer- Scriban-based template parsing and renderingServiceCollectionExtensions- Dependency injection setup
ScribanBuiltinFunctionsExtensions- Base Scriban functionsScribanStringFunctionsExtensions- Custom string manipulation functions
Run the test suite:
dotnet test NFramework.Core.Template.Engine.Tests.csproj
dotnet test NFramework.Core.Template.Scriban.Tests.csprojFor development setup and contribution guidelines, see CONTRIBUTING.md.
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
- NFramework β The parent framework
- NFramework.Core.CLI β CLI framework library