Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/noxum/compiledhandlebars

Compiled Handlebars for C# - Compiling Handlebars-Templates into native C# code for performant and type-safe serverside HTML rendering.
https://github.com/noxum/compiledhandlebars

asp-net aspnet aspnet-mvc handlebars handlebars-template hbs viewengine

Last synced: about 1 month ago
JSON representation

Compiled Handlebars for C# - Compiling Handlebars-Templates into native C# code for performant and type-safe serverside HTML rendering.

Awesome Lists containing this project

README

        

Compiled Handlebars for C#
==========================

Compiling Handlebars-Templates into native C# code for performant and type-safe serverside HTML rendering.
### About
This compiler is the result of Jakob Demler's bachelor thesis which covers the approach, design decisions, implementation details and its evaluation and can be found [here](ReadmeAssets/CompiledHandlebars_Jakob-Demler.pdf)

### Project Status
This project is currently in a beta phase.

### Features
+ Get your type-errors at design-time
+ Resolving partial and helper calls at design-time
+ Trivial invocation: TemplateName.Render(viewModel);
+ Minimal dependencies: resulting code just depends on System, System. Net and System.Text

#### Performance
A performance comparison was made against the microbenchmarks from the handlebars.js repository:
https://github.com/wycats/handlebars.js/tree/master/bench

| Microbenchmark | handlebars.js | CompiledHandlebars | Speedup |
|----------------|---------------|--------------------|---------|
|arrayeach|391 ops/ms|3039 ops/ms|7.77|
|complex|120 ops/ms|1180 ops/ms|9.83|
|data|295 ops/ms|1333 ops/ms|4.51|
|depth1|228 ops/ms|3693 ops/ms|16.20|
|depth2|63 ops/ms|1515 ops/ms|24.04|
|partial-recursion|125 ops/ms|1895 ops/ms|15.16|
|partial|211 ops/ms|905 ops/ms|4.29|
|paths|2060 ops/ms|4646 ops/ms|2.25|
|string|5563 ops/ms|13964 ops/ms|2.51|
|variables|1991 ops/ms|4027 ops/ms|2.02|

### Usage

#### Visual Studio Integration
Just install the vsix package from the CustomTool project and restart Visual Studio. Add a new Handlebars template to your solution (ending on .hbs) and then add "HandlebarsCompiler" to the file's CustomTool property.
The compiler will be invoked every time the Handlebar template is saved and will create a {templatename}.hbs.cs file containing the generated code.

#### Basic Usage
Every Handlebars-Template needs a type which it renders.
As an example a class named "PersonModel" will serve:
```CSharp
namespace ViewModels
{
public class PersonModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
public List EMailAddresses { get; set; }
}
}
```

Now, we must communicate the type to the HandlebarsCompiler. At the beginning of each Handlebars-Template there needs to be a socalled ModelToken:
```Handlebars
{{model NamespacePath.ClassName}}
```
For our example that would be:
```Handlebars
{{model ViewModels.PersonModel}}
```
Note, that the type inside the ModelToken can also be a base class or interface of the actual ViewModel that is passed to the template.

The rest of the Handlebars-Templates follows standard Handlebars syntax and semantics.
Here is the full example:
```Handlebars
{{model ViewModels.PersonModel}}

Hello {{FirstName}} {{LastName}}


You are {{Age}} years old and you have
{{#if EMailAddresses}}
following email addresses:


    {{#each EMailAddresses}}
  • {{this}}

  • {{/each}}

{{else}}
no email addresses.
{{/if}}
```

#### Partials
Partials do not need to be registered. Just be sure to compile the partial before the Handlebars-Template that uses that partial. For everything else standard handlebars.js logic applies.

#### Helper Functions
CompiledHandlebars allow the usage of helper functions. These must be static, return a string and be annotated by an attribute. Parameters are checked if they match at compile-time so overloading is possible. Other than that, they have no restrictions an can be placed anywhere in your codebase.

```CSharp
[CompiledHandlebarsHelperMethod]
pulic static string FullName(PersonModel model)
{
return string.Concat(model.FirstName, " ", model.LastName);
}
```

#### Layout Functionality
CompiledHandlebars offers differing functionality regarding layouts:
Any HandlabarsTemplate can be rendered inside a HandlebarsLayout. HandlebarsLayouts differ from normal HandlebarsTemplates due to a special {{body}} token:
```Handlebars
{{model ViewModels.IPageModel}}

{{Title}}
{{#if Keywords}}{{/if}}

{{body}}

{{Headline}}


{{Content}}