A small, simple, and extendable C# library for generating static sites, inspired by Metalsmith
Generating a static website from a directory is as simple as this:
new MetalsharpProject()
.AddInput("Site")
.UseFrontmatter()
.UseMarkdown()
.AddOutput("Static")
.Build();Metalsharp is:
- Small — uses the smallest amount of code necessary to get the job done,
- Simple — straightforward API with easy-to-understand documentation, and
- Extendable — creating and publishing plugins is as easy as possible.
Metalsharp targets .NET 10 and is available on NuGet:
dotnet add package Metalsharp
Prefer to try it without setting up a project? Metalsharp works great with .NET file-based apps — see the Create a Website tutorial for a walkthrough that builds a complete site with nothing but a single .cs file.
A Metalsharp project doesn't require any particular directory layout, but the following structure works well for most sites:
ProjectFolder
├── Site
│ ├── SomeFile.md
│ └── SomeOtherFile.md
├── Static
│ └── style.css
└── README.md
Here, ProjectFolder is the root of the project. Anything unrelated to the generated site — your build script, README, and so on — can live at this level. Content that Metalsharp will process goes in Site, and files that should be copied straight through to the output, such as stylesheets and images, go in Static. Neither of these directory names is a requirement; use whatever structure fits your project.
Let's walk through the example above. The quickstart covers the basics in more depth, and Create a Website with Metalsharp walks through a complete, practical project.
-
Instantiate a
MetalsharpProjectand read in the files you want to work with:new MetalsharpProject() .AddInput("Site")
-
Invoke a plugin by passing an instance to
Use.Frontmatterreads each file's frontmatter into its metadata:.Use(new Frontmatter())
-
If a plugin has a public parameterless constructor, you can reference its type instead:
.Use<Frontmatter>()
-
Most of the plugins that ship with Metalsharp —
Frontmatterincluded — also provide an extension method that does the same thing, for convenience:.UseFrontmatter()
-
Markdownworks the same way; it converts Markdown files in the input into HTML files in the output:.UseMarkdown()
-
Add any files that should be copied straight through to the output, such as static assets:
.AddOutput("Static")
-
Finally, call
Buildto write the output files to disk:.Build();
Creating a Metalsharp plugin is straightforward — see Create a Plugin for Metalsharp for a full walkthrough. At its core, a plugin only needs to implement IMetalsharpPlugin, which has a single method, Execute. Here's the Markdown plugin that ships with Metalsharp:
public class Markdown : IMetalsharpPlugin
{
public void Execute(MetalsharpProject project)
{
foreach (var file in project.InputFiles.Where(f => f.Extension is ".md" or ".markdown"))
{
var fileText = Markdig.Markdown.ToHtml(file.Text);
var filePath = Path.Combine(file.Directory, file.Name + ".html");
project.LogDebug($"Converting Input file {file.FilePath} to Output file {filePath}");
project.OutputFiles.Add(new MetalsharpFile(fileText, filePath)
{
Metadata = new Dictionary<string, object>(file.Metadata)
});
}
}
}Metalsharp.Documentation contains generated API reference documentation and hand-written tutorials.
The source is fully documented with XML comments. Metalsharp.Documentation/api.md is generated from those comments by GenerateApiDoc.cs.
For questions or help using Metalsharp, please use the Metalsharp Discord rather than opening an issue.
Contributions are welcome in whatever form suits you — bug reports, documentation fixes, new plugins, or pull requests against the core library.
Metalsharp is licensed under the MIT License.