Mustache.MSBuild 0.3.1

There is a newer version of this package available.
See the version list below for details.
dotnet add package Mustache.MSBuild --version 0.3.1                
NuGet\Install-Package Mustache.MSBuild -Version 0.3.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="Mustache.MSBuild" Version="0.3.1">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Mustache.MSBuild --version 0.3.1                
#r "nuget: Mustache.MSBuild, 0.3.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.
// Install Mustache.MSBuild as a Cake Addin
#addin nuget:?package=Mustache.MSBuild&version=0.3.1

// Install Mustache.MSBuild as a Cake Tool
#tool nuget:?package=Mustache.MSBuild&version=0.3.1                

Mustache Templates for MSBuild and .NET Project

Mustache.MSBuild allows you to render Mustache templates when a .NET project is built.

Its goal is to be a simpler, cross-platform alternative to T4 Text Templates.

For a general tutorial on Mustache templates, see: https://www.tsmean.com/articles/mustache/the-ultimate-mustache-tutorial/

How To Use

To use Mustache.MSBuild, first reference its NuGet package in your project:

  <ItemGroup>
    <PackageReference Include="Mustache.MSBuild" Version="XXX">
      
      <PrivateAssets>all</PrivateAssets>
    </PackageReference>
  </ItemGroup>

Then create your .mustache template file; for example (file name: HelloFriends.txt.mustache):

I hereby greet all my friends:

{{#friends}}
  Hello {{.}}!
{{/friends}}

Nice to know you all!

The output file name will be the same as the file name of the mustache file - but without the .mustache extension.

Next we need a data file which provides the data for the template. This must be a .json file. For the example above, we use the following contents (file name: HelloFriends.txt.json):

{
    "friends": [ "Alice", "Bob", "Charlie" ]
}

Note: The name of the data file must be the same as the output file but with .json added.

Now, when you compile your project, Mustache.MSBuild will generate the following file (file name: HelloFriends.txt):

I hereby greet all my friends:

  Hello Alice!
  Hello Bob!
  Hello Charlie!

Nice to know you all!

Tip: Organize Files in .csproj

To keep you template, output, and data file neatly organized, you can use <DependentUpon> in your .csproj file:

  <ItemGroup>
    <None Update="MyFriends\HelloFriends.txt">
      <DependentUpon>HelloFriends.txt.mustache</DependentUpon>
    </None>
    <None Update="MyFriends\HelloFriends.txt.json">
      <DependentUpon>HelloFriends.txt.mustache</DependentUpon>
    </None>
  </ItemGroup>

Important: <DependentUpon> must only contain a file name. Specifying a full path here will break it (when the solution is reloaded).

Automatic Placeholders

Mustache.MSBuild automatically provides the following placeholders:

Name Description
{{TemplateFile}} File name of the template file

Compatibility

Mustache.MSBuild is a MSBuild "plugin".

As such, it is compatible both with .NET Framework and .NET (Core) projects.

However, it requires a modern SDK-style project. Legacy (non-SDK-style) projects are not supported. (For some details on how to tell them apart, see Identify the project format.)

Input/Output Encoding

Mustache.MSBuild uses the template file's text encoding as text encoding for the output file.

It recognizes all text encodings that use a BOM (i.e. UTF-8, UTF-16, UTF-32). If no BOM is present, UTF-8 is assumed.

If you need a different text encoding, you have to specify it in the data file like so:

{
    "$Encoding": "Windows-1252"
}

The value is passed to .NET's Encoding.GetEncoding() method. Any value accepted by this method can be used. For a list of possible encodings, see the WebName documentation.

Note: The data file (JSON) must/should always be encoded in UTF-8.

Comparison to T4 and Source Generators

In the .NET space there are two other (popular) ways to generate files: T4 Text Templates and Source Generators. This section compare these two solutions with Mustache.MSBuild.

Mustache.MSBuild T4 Templates Source Generators
Generate from Template Template Source Code (separate project)
Can generate Any text file Any text file Source Code
Cross platform Yes No, Windows only Yes
Visible output file Yes Yes No
Template change requires VS restart No No Yes
Output built During build On file save During build

The biggest downsides of T4 templates are:

  • Only available in Visual Studio on Windows.
  • (Looks complicated.)
  • (Brings a scary "this template can damage your computer" dialog when being used.)

The biggest downsides of Source Generators are:

  • Creating a custom "template" requires a separate .NET project.
  • Changes to the "template" require you to close Visual Studio down (because Visual Studio can't unload the source code generator assembly).

Depending on your use case, there are additional downsides of Source Generators:

  • Can only generate .NET source code, no other file types.
  • Generated source code is not place in a file on disk (i.e. the actual generated source code is not visible).

Some Notes

Due to the way MSBuild works, any non-existing file that's newly created during a build is only picked up in the next MSBuild run. Normally, this is not a problem because the files generated by this package are supposed to be check in under version control.

Due to the way Visual Studio works, updating the version of this NuGet package while Visual Studio is running will not result in the new version being used. The (simplified) reason is that Visual Studio can load the assembly of this package only once - but can't unload it afterwards (to then load the new version). For the new version to be used, you have to restart Visual Studio.

Credits

This project uses Stubble under the hood for processing the Mustache templates.

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. 
.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.

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
0.3.3 731 10/15/2022
0.3.2 458 10/9/2022
0.3.2-preview4 310 10/9/2022
0.3.2-preview3 348 10/9/2022
0.3.2-preview2 419 10/9/2022
0.3.2-preview1 192 10/9/2022
0.3.1 527 9/15/2022
0.2.0 416 9/4/2022
0.2.0-preview-4 175 9/4/2022
0.2.0-preview-3 193 9/4/2022
0.2.0-preview-2 180 9/3/2022
0.2.0-preview-1 186 9/1/2022
0.1.0 413 8/11/2022
0.1.0-preview6 207 8/11/2022
0.1.0-preview5 199 8/10/2022
0.1.0-preview4 176 8/10/2022