https://github.com/jpvenson/morestachio
Lightweight, powerful, flavorful, template engine.
https://github.com/jpvenson/morestachio
formatters hacktoberfest mustache netstandard stream template-engine templating
Last synced: about 2 months ago
JSON representation
Lightweight, powerful, flavorful, template engine.
- Host: GitHub
- URL: https://github.com/jpvenson/morestachio
- Owner: JPVenson
- License: other
- Created: 2017-11-07T22:09:16.000Z (almost 8 years ago)
- Default Branch: master
- Last Pushed: 2024-12-01T00:22:00.000Z (11 months ago)
- Last Synced: 2025-08-11T15:21:50.807Z (2 months ago)
- Topics: formatters, hacktoberfest, mustache, netstandard, stream, template-engine, templating
- Language: C#
- Homepage:
- Size: 3.68 MB
- Stars: 52
- Watchers: 5
- Forks: 11
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- Funding: .github/FUNDING.yml
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
# Morestachio

[](https://app.fossa.io/projects/git%2Bgithub.com%2FJPVenson%2Fmorestachio?ref=badge_shield)
[](https://jeanpierrebachmann.visualstudio.com/Morestachio/_build?definitionId=3&view=ms.vss-pipelineanalytics-web.new-build-definition-pipeline-analytics-view-cardmetrics)

A Lightweight, powerful, flavorful, templating engine for C# and other .net-based languages. Its a fork of Mustachio.
## Need help?
Need general help? open a [Discussion](https://github.com/JPVenson/morestachio/discussions/new)
Found a bug? open a [Bug](https://github.com/JPVenson/morestachio/issues/new?assignees=&labels=&template=bug_report.md)#### Installing Morestachio:
|Project Nuget|Github|Status|Description|
|---|---|---|---|
| Morestachio
[](https://www.nuget.org/packages/Morestachio/)  | [](https://github.com/JPVenson/morestachio/releases) | [](https://dev.azure.com/JeanPierreBachmann/Mustachio/_build/latest?definitionId=3) [](https://jeanpierrebachmann.visualstudio.com/Morestachio/_release?view=all&_a=releases&definitionId=1)| The base Morestachio lib |
| Morestachio.Linq
[](https://www.nuget.org/packages/Morestachio.Linq/)
 | | [](https://dev.azure.com/JeanPierreBachmann/Mustachio/_build/latest?definitionId=3) [](https://jeanpierrebachmann.visualstudio.com/Morestachio/_release?view=all&_a=releases&definitionId=1) | [Linq formatter](https://github.com/JPVenson/morestachio/wiki/Predefined-Formatter#class-dynamiclinq) |
| Morestachio.Runner
[](https://www.nuget.org/packages/Morestachio.Runner/)
 | | [](https://dev.azure.com/JeanPierreBachmann/Mustachio/_build/latest?definitionId=3) [](https://jeanpierrebachmann.visualstudio.com/Morestachio/_release?view=all&_a=releases&definitionId=1) | An [executable interface](https://github.com/JPVenson/morestachio/wiki/Morestachio-Runner) for invoking a Morestachio Template |
| Morestachio.Newtonsoft.Json
[](https://www.nuget.org/packages/Morestachio.Newtonsoft.Json/)
 | | [](https://dev.azure.com/JeanPierreBachmann/Mustachio/_build/latest?definitionId=3) [](https://jeanpierrebachmann.visualstudio.com/Morestachio/_release?view=all&_a=releases&definitionId=1) | Newtonsoft Json [types support](https://github.com/JPVenson/morestachio/wiki/Newtonsoft.Json-support) |
| Morestachio.System.Text.Json
[](https://www.nuget.org/packages/Morestachio.System.Text.Json/)
 | | [](https://dev.azure.com/JeanPierreBachmann/Mustachio/_build/latest?definitionId=3) [](https://jeanpierrebachmann.visualstudio.com/Morestachio/_release?view=all&_a=releases&definitionId=1) | System.Text Json [types support](https://github.com/JPVenson/morestachio/wiki/System.Text.Json-support) |
| Morestachio.System.Xml.Linq
[](https://www.nuget.org/packages/Morestachio.System.Xml.Linq/)
 | | [](https://dev.azure.com/JeanPierreBachmann/Mustachio/_build/latest?definitionId=3) [](https://jeanpierrebachmann.visualstudio.com/Morestachio/_release?view=all&_a=releases&definitionId=1) | XDocument [types support](https://github.com/JPVenson/morestachio/wiki/System.Xml-support) |
| Morestachio.Extensions.Logging
[](https://www.nuget.org/packages/Morestachio.Extensions.Logging/)
 | | [](https://dev.azure.com/JeanPierreBachmann/Mustachio/_build/latest?definitionId=3) [](https://jeanpierrebachmann.visualstudio.com/Morestachio/_release?view=all&_a=releases&definitionId=1) | Microsoft.Extensions.Logging.ILogger [support]([https://github.com/JPVenson/morestachio/wiki/System.Xml-support](https://github.com/JPVenson/morestachio/wiki/Microsoft.Extensions.Logging)) |#### What's this for?
*Morestachio* allows you to create simple text-based templates that are fast and safe to render. It is optimized for WebServers and offers a high degree of customization with its formatter syntax.
#### Morestachio Playground:
Try it out, without consequenses. The Morestachio online editor allows you to create templates within your browser:
[Editor](https://morestachio.jean-pierre-bachmann.dev/)#### How to use Morestachio:
```csharp
// Your template
var sourceTemplate = "Dear {{name}}, this is definitely a personalized note to you. Very truly yours, {{sender}}";// Parse the template into the document tree.
var document = await ParserOptionsBuilder
.New() //creates a new builder that inherts all default values
.WithTemplate(sourceTemplate) //sets the template for that builder
.BuildAndParseAsync(); //Builds the template and calls ParseAsync() on the returned ParserOptions// Create the values for the template model:
dynamic model = new ExpandoObject();
model.name = "John";
model.sender = "Sally";
// or with dictionarys
IDictionary model = new Dictionary();
model["name"] = "John";
model["sender"] = "Sally";
//or with any other object
var model = new { name= "John", sender= "Sally" };//create an object based renderer or a compiled renderer
//the renderer is reusable and ThreadSave
var renderer = document.CreateRenderer();// Render the template with your model and get the result as a string
var content = renderer.RenderAndStringify(model); // Dear John, this is definitely a personalized note to you. Very truly yours, Sally
```##### Key Features
Morestachio is build upon Mustachio and extends the mustachio syntax in a a lot of points.1. each object can be formatted by adding [formatter](https://github.com/JPVenson/morestachio/wiki/Formatter) to morestachio
2. Templates will be parsed as [streams](https://github.com/JPVenson/morestachio/wiki/ParserOptions#template-itemplatecontainer-property) and will create a new stream for its [output](). This is better when creating larger templates and best for web as you can also [limit the length](https://github.com/JPVenson/morestachio/wiki/ParserOptions#maxsize-long-property) of the "to be" created template to a certain size and write the result ether directly to an output stream or the Disc.
3. [Its Lightning fast](https://github.com/JPVenson/morestachio/wiki/Performance). Even unreasonably huge templates that contain >5000 instructions can be executed in around *0.5 secounds*
4. Morestachio accepts any object as source
5. [Cancellation](https://github.com/JPVenson/morestachio/wiki/ParserOptions#timeout-timespan-property) of Template generation is supported
6. Async calls are supported (For Formatters)
7. No External Depedencies for Morestachio.dll.
8. Support for several .Net framworks:
- NetStandard (netstandard2.0; netstandard2.1; see [.NET implementation support](https://docs.microsoft.com/en-us/dotnet/standard/net-standard#net-implementation-support))
- Net5.0, Net6.0
9. Build in [Localization support](https://github.com/JPVenson/morestachio/wiki/Localisation) and [Logging support](https://github.com/JPVenson/morestachio/wiki/ParserOptions#logger-ilogger-property)
10. Supports user [Encoding](https://github.com/JPVenson/morestachio/wiki/ParserOptions#encoding-encoding-property) of the result template
11. Supports [Template Partials](https://github.com/JPVenson/morestachio/wiki/Templates-Partials) `{{#import 'secondary_template' }}`
12. [Complex paths](https://github.com/JPVenson/morestachio/wiki/Keywords#paths) are supported `{{ this.is.a.valid.path }}` and `{{ ../this.goes.up.one.level }}` and `{{ ~.this.goes.up.to.Root }}`
13. [Loops](https://github.com/JPVenson/morestachio/wiki/Keywords#do--while--repeat---blocks) with `#each` & `#do` & `#while` & `#repeat`
14. [Object Enumeration](https://github.com/JPVenson/morestachio/wiki/Keywords#each--every---blocks) with `#each data.?`
15. Formatters can be declared in C# and be called from the template to provide you with a maximum of freedom
16. Extensive (275) [Build-In list of Formatters](https://github.com/JPVenson/morestachio/wiki/Predefined-Formatter) for a broad usecases
17. The Parser produces a Serilizable [Document Tree](https://github.com/JPVenson/morestachio/wiki/Document-Tree) that can be send to clients to provide a rich user edit experienceCheckout the Github Wiki for an extensive documentation:
https://github.com/JPVenson/morestachio/wiki
**Template partials** ARE a great feature for large scale template development.You can create a Partial with the `{{#declare NAME}}Partial{{/declare}}` syntax. You can navigate up inside this partials. Partials can also be nested but are currently restricted to a maximum recursion of 255 depth. The programmer has the choice to define a behavior that ether throws an Exception or does nothing and ignores any deeper recusions.
A Partial must be declared before its usage with `{{#import 'NAME'}}` but you can use a partial to create hirarical templates.
You can even inject your predefined Partials into all of your Templates by utilizing the `PartialsStore`. Use your own `IPartialStore` or a build in one with `ParserOptionsBuilder.WithDefaultPartialStore(store => {...add partials to store...})`.
###### Infos about new features
Its possible to use plain C# objects they will be called by reflection.
Also you can now set the excact size of the template to limit it (this could be come handy if you are in a hostet environment) use the `ParserOptionsBuilder.WithMaxSize()` option to define a max size. It will be enforced on exact that amount of bytes in the stream.##### Variable Output
One mayor component is the usage of Variable output strategies in morestachio.
The output handling is done by a `IByteCounterStream` that wraps your specific output. This can ether be a `Stream`, `TextWriter`, `StringBuilder` or anything else. For thoese types Morestachio has pre defined Implementations named `ByteCounterStream`, `ByteCounterTextWriter` and `ByteCounterStringBuilder`. All thoese types are enforcing the `ParserOptionsBuilder.WithMaxSize()` config if set and will write your template with the set `ParserOptionsBuilder.WithEncoding()`
###### Formatter
With Morestachio you can invoke C# methods from you template, so called 'Formatters'. There are [Build in formatters](https://github.com/JPVenson/morestachio/wiki/Predefined-Formatter) you can call in any template, registered via the `DefaultFormatterService.Default` class. When you add a formatter in the default service, it will be availible in every template. You can also add formatters per-template via the `ParserOptionsBuilder.WithFormatters` service.To Invoke a formatter from you template use the Function syntax:
```csharp
{{Just.One.Formattable.FormatterToCall().Thing}}
```
This links a c# function named "FormatterToCall".You can register delegates by using `ParserOptionsBuilder.WithFormatter(...)` or you can create a `public static class` that has methods attributed with the `MorestachioFormatterAttribute` and add them via the `ParserOptionsBuilder.WithFormatters` or you can use an instance method attributed with the `MorestachioFormatterAttribute`.
The formatter CAN return a new object on wich you can call new Propertys or it can return a string.
There are formatter prepaired for types implementing the `IFormattable` interface. This includes all Primitve types. That means for example that you can call the `ToString` formatter on any `DateTime`:
```csharp
{{MyObject.DateTime.ToString("D")}} <-- this will resolve a property "MyObject" and then "DateTime" and will call ToString on it with the argument "D"
```**Formatter References**
Can be used to reference another property/key in the template and then use it in a Formatter. Everything that is not a string (ether prefixed and suffixed with " or ') will be threaded as an expression that also can contain formatter calls
```csharp
{{MyObject.Value.ToString(Key)}}
```
This will call a formatter that is resposible for the type that `Value` has and will give it whats in `Key`. Example:
```csharp
//create the template
var template = "{{Value.ToStringX(Key)}}";
//create the model
var model = new Dictionary();
model["Value"] = DateTime.Now;
model["Key"] = "D";
//now add a formatter for our DateTime and add it to the ParserOptionsvar document = await ParserOptionsBuilder
.New()
.WithTemplate(template)
// Value | Argument | Return
.WithFormatter(new Func((value, argument) => {
//value will be the DateTime object and argument will be the value from Key
return value.ToString(argument);
}, "ToStringX")
.BuildAndParseAsync();document.CreateRenderer().RenderAndStringify(model); // Friday, September 21, 2018 ish
```
## License
[](https://app.fossa.io/projects/git%2Bgithub.com%2FJPVenson%2Fmorestachio?ref=badge_large)