«Tilde, a static blog generator

Posted on April 6, 2013

tilde ## Huh?

Tilde uses Razor for templating, FSharp.Formatting for Markdown and F# highlighting and Prettify for highlighting other languages. The directory layout is quite similar to Jekyll check out my (quite hacked together!) blog source here.

Posts are written in Markdown and are post-processed as Razor templates. Heres an example of the top of this page

[lang=markdown]
@@{
  Layout = "Post";
  Title = "Tilde, a static blog generator";
  Description = "A Static blog generator using Razor and FSharp.Formatting";
  Tags = new string[] {"F#", "Blogging", "FSharp.Formatting", "Razor"};
  Meta["CustomEntry"] = "Woo";
}

![tilde](/content/images/tilde2.png)
## Huh?

Tilde uses [Razor](https://github.com/Antaris/RazorEngine) for templating, [FSharp.Formatting](https://github.com/tpetricek/FSharp.Formatting)

All the usual Markdown syntax should work, aswell as anything supported by RazorEngine for example typing @@DateTime.Now would produce @DateTime.Now this allows for some pretty awesome compile time hackery for example the following chunk of code written anywhere in the blog post:

[lang=csharp]
@@{
  var client = new System.Net.WebClient();
  var tracks = client.DownloadString("http://ws.audioscrobbler.com/1.0/user/ike_x/recenttracks.rss");
  var rgx = new System.Text.RegularExpressions.Regex("<title>(.*?)</title>");
  @@rgx.Matches(tracks)[1].Groups[1];
}
@{ var client = new System.Net.WebClient(); var tracks = client.DownloadString(“http://ws.audioscrobbler.com/1.0/user/ike_x/recenttracks.rss”); var rgx = new System.Text.RegularExpressions.Regex(“ (.*?)

“); @rgx.Matches(tracks)[1].Groups[1]; }

Should print out the last song I was listening to when this blog was last compiled. (Hopefully above!).

Unfortunately at the moment the markdown will be interpreted inside @@{ } so anything that would be interpreted as markdown will corrupt the code. Also since this evaluated every re-compile of the site depending on what you have this could increase page compile times rapidly.

FSharp.Formatting and Syntax highlighting

FSharp.Formatting, allows us to export F# snippets with syntax highlighting and tooltips, try hovering your mouse over the code below.

[name=example.fsx]
/// Fibonacci Number formula
let rec fib n =
    match n with
    | 0 | 1 -> n
    | _ -> fib (n - 1) + fib (n - 2)
 
/// Another approach - a lazy infinite sequence of Fibonacci numbers
let fibSeq = Seq.unfold (fun (a,b) -> Some(a+b, (b, a+b))) (0,1)
 
// Print even fibs
[1 .. 10]
|> List.map     fib
|> List.filter  (fun n -> (n % 2) = 0)
|> printList
 
// Same thing, using a list expression
[ for i in 1..10 do
    let r = fib i
    if r % 2 = 0 then yield r ]
|> printList
// taken from: http://en.wikipedia.org/wiki/F_Sharp_(programming_language)#Examples

F# Blocks begin with the normal markdown 4+ spaces in then a name field followed by the code, for example the code above.

[lang=html]
[linenums=false]
 [name=example.fsx]
/// Fibonacci Number formula
let rec fib n =
    match n with
    | 0 | 1 -> n
    | _ -> fib (n - 1) + fib (n - 2)
 

Unfortunately :( there is no tooltips for other languages.

[lang=ruby]
require "sinatra"

class Example < Sinatra::Base
  get "/" do  
    "Why hello there!"
  end
end

Which was created with the following

[lang=html]
[linenums=false]
 [lang=ruby]
require "sinatra"

class Example < Sinatra::Base
  get "/" do  
    "Why hello there!"
  end
end

Site, Posts, Templating, Partials

Tilde uses templates from the _layouts folder, for example my blog has Post.cshtml which references Default.cshtml and includes GA.cshtml as a partial so the render chain looks something like this:

[lang=none]
[linenums=false]
[Markdown Post] -> (Post.cshtml -> GA.cshtml) -> Default.cshtml

Templates follow the same general Razor rules, and contain a @@RenderBody to fill out the contents. @@RenderPart is used to render partials, for my blog I have disqus and google analytics being included this way.

Variables are scoped per file for example a variable defined here cannot be seen by the template i specified at the top. Except for the ViewBag and the following Title, Description, Tags, Meta which are available from the template and from other pages under Site.Posts.

Meta is a dictionary which can include any custom variables you want the template to be able to access.

Site is available to templates and at the moment contains just Posts which is an array of all the rendered blog posts and the properties above. Site can be accessed from blog posts but depending on the current compile order can be unpredictable. An example of a page using this is index.cshtml from this blog.

Theres probably a lot more to write, but my head is killing me. This was hacked together over a friday night i’d imagine its filled with bugs and other nice things. Its available here at github. I’m using it to generate this blog!