Wing Beats

Project Description

Wing Beats 0.9 is an internal little language (DSL) for creating XHTML. It is based on F# and includes an ASP.NET MVC view engine, but can also be used solely for it's capability of creating XHTML.


  • View engine for ASP.NET MVC 2
  • Generates valid XHTML 1.0 Strict. Choose between writing all markup in one line or have it formatted for the human eye.
  • Tight integration with F# in ways an external language never can achieve.
  • Wing Beats takes advantage of the terse but flexible syntax of F#. This makes it feel almost like an external language in its conciseness.
  • Create static templates with placeholders where you can put content dynamically.


  • Visual Studio 2010
  • .NET 4

Wing Beats 0.9 is a language for creating XHTML. There are other alternatives for this like the ASP.NET default view engine (WebForms), NHaml, NDjango or Spark.

Wing Beats differs in that it is implemented directly in F# (it's an internal language) and therefore you are liberated from the separation of your "host" language. This allows your views to be extraordinary flexible and easy to reuse. For example, you can easily compile them into a library and use them in another project. This way you can build your own collection of reusable components, the way you do with other code.

Below some sample code:

module MyProject.Views.Home
open WingBeats.Xhtml
open WingBeats.Xml

let e = XhtmlElement()

/// A template with the placeholders "title" and "content"
let masterTemplate =
    e.Html [
        { Name = "lang"; NS = {Prefix = "xml"; Uri = ""} }, "en"
        { Name = "lang"; NS = {Prefix = ""   ; Uri = ""        } }, "en"
    ] [
        e.Head [ 
            e.Title [ +"title" ]
            e.Link "[ type=text/css; rel=stylesheet; href=/styles/main.css ]"
            e.Script "[ type=text/javascript; src=/scripts/main.js ]" []
        e.Body [
            e.Div "#page" [
                e.H1 [ +"title" ]

/// A view method. The result is sent to the view engine, where the
/// content is added to the template
let Index (model : string * string) = 
    let title, content = model

    masterTemplate, [ 
      "title"  , fun () -> &title
      "content", fun () -> e.Div "#content" & content

Last edited Oct 7, 2010 at 8:12 PM by Jonsi, version 63