FSTemplate
F# templating engine for ASP.NET. Inspired by Elm View functions
Write your ASP.NET templates in pure F#!!
How it works
- Template is located in
Views
folder. - Script (*.fsx) is compiled using F# Compiler Services.
- By using reflection, render function is exctracted from the compiled assembly.
- Render function is executed by passing
Model
orViewContext
as a parameter. - Result of type
Node
is transformed into html.
Template requirements
- Template script contains exactly one function with
[<Render>]
attribute on top - Render function has one of the following signatures:
Model -> Node
ViewContext -> Node
Model -> ViewContext -> Node
ViewContext -> Model -> Node
ViewContext * Model -> Node
Model * ViewContext -> Node
How to add
Install following NuGet package
PM> Install-Package FSTemplate.Mvc
Add following code in your Global.asax.cs Application_Start()
method:
FSTemplateBootstrapper.Bootstrap();
ViewEngines.Engines.Clear(); //optional
ViewEngines.Engines.Add(new FSViewEngine());
Example
Let's say you have HomeController
that returns a View
with some model:
public ActionResult Index()
{
var model = new IndexModel
{
Name = "Hello World",
Values = new[] { 0, 1, 2, 3, 4 }
};
return View(model);
}
and you have following Views
folder structure:
-
references.fsx - contains all references that is needed for template compilation
// actual FSTemplate library #r "../bin/FSTemplate.dll" // web-app dll for referencing models or other classes #r "../bin/FSTemplate.Sample.dll" // other dependencies...
-
baseLayout.fsx (optional) - base layout for the page. For example
#load "references.fsx" open FSTemplate.Html open FSTemplate let baseLayout body = html [stylesheet "Content/Site.css"] (body @ [script "Scripts/Site.js"])
-
Home/Index.fsx - template for
Index
action#load "../references.fsx" #load "../baseLayout.fsx" open FSTemplate.Html open FSTemplate open FSTemplate.Sample.Models let transformValuesToLi values = values |> Array.map (fun x -> li [] [text (string x)]) |> List.ofArray [<Render>] let index (model: IndexModel) = BaseLayout.baseLayout [ div [] [ text model.Name; ul [] (model.Values |> transformValuesToLi) ] ]
As a result request to /Home/Index
returns following page:
Todo
- Unit tests
- Implementation of all html tags
- Integration tests
- ASP.NET Core bindings
- NancyFX bindings
- Config sections and loading configuration
- CSS rendering implementation