Introducing NHaml - An ASP.NET MVC View Engine

Posted by Andrew on December 19, 2007

NHaml (pronounced enamel) is a pure .NET implementation of the popular view engine. From the Haml website:

“Haml is a markup language that‘s used to cleanly and simply describe the XHTML of any web document, without the use of inline code. Haml functions as a replacement for inline page templating systems such as PHP, ERB, and ASP. However, Haml avoids the need for explicitly coding XHTML into the template, because it is actually an abstract description of the XHTML, with some code to generate dynamic content.”

In other words, NHaml is an external for XHTML. It’s primary qualities are it’s simplicity, terseness, performance and that it outputs nicely formatted XHTML. Additionally, the NHaml view engine provides support for Rails style layouts and partials – more on that below.

An example is the best way to grok how NHaml works. Below we have a typical view targeting the default Web Forms view engine. Observe the proliferation of angle-brackets, closing tags and general cruft.

~/Views/Products/List.aspx

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true" 
    CodeBehind="List.aspx" Inherits="MvcApplication5.Views.Products.List" Title="Products" %>
<asp:Content ContentPlaceHolderID="MainContentPlaceHolder" runat="server">
  <h2><%= ViewData.CategoryName %></h2>
  <ul>
    <% foreach (var product in ViewData.Products) { %>
      <li>
        <%= product.ProductName %> 
        <div class="editlink">
          (<%= Html.ActionLink("Edit", new { Action="Edit", ID=product.ProductID })%>)
        </div>
      </li>
    <% } %>
  </ul>
  <%= Html.ActionLink("Add New Product", new { Action="New" }) %>
</asp:Content>

Now, let us bask in the glory of the NHaml version:

~/Views/Products/List.haml

%h2= ViewData.CategoryName
%ul
  - foreach (var product in ViewData.Products)
    %li
      = product.ProductName 
      .editlink
        = Html.ActionLink("Edit", new { Action="Edit", ID=product.ProductID })
= Html.ActionLink("Add New Product", new { Action="New" })

There are a couple of things going on here. First, NHaml uses indentation (2 spaces) as an alternative to closing tags. Second, the first non-whitespace character in a line can describe how the line should be processed. For example, the first line in the example above starts with a ’%’, which directs NHaml to process that line as an XHTML tag. These directives are called Markup Rules and are discussed in detail in the Reference section below.

Download & License

NHaml is open source and released under the MIT license so go ahead and download the source, kick the tires and let me know what you think. Oh, and if/when you find an issue let me know or submit a patch.

Using NHaml

Configuring the ASP.NET MVC framework to use NHaml is as simple as referencing Mindscape.NHaml.ViewEngine.dll and putting the following line at the end of the Application_Start method in the Global.asax.cs file.

ControllerBuilder.Current.SetDefaultControllerFactory(typeof(NHamlControllerFactory));

NHaml view templates should have a .haml extension and are placed under the Views project folder in the normal manner.

Partials & Layouts

Currently, unlike Rails, the ASP.NET MVC framework delegates layout and partial handling to the view engine. Therefore, NHaml provides it’s own layout & partial system.

Partials

Partials are small reusable sub-views available within a single controller context. NHaml implements a Rails-like partial system. Any view template beginning with an ‘_’ is considered a partial. To use a partial simply use the NHaml ‘_’ markup rule like so:

~/Views/Products/List.haml

- foreach (var product in ViewData.Products)
  %li
    _ Product

In this example NHaml will replace the line ”_ Product” with the contents of the file _Product.haml in the current controller”s view folder (~/Views/Products)

~/Views/Products/_Product.haml

= product.ProductName 
%span.editlink
  = Html.ActionLink("Edit", new { Action="Edit", ID=product.ProductID })

At compile-time, both layouts and partials are merged into a single view and so any ViewData context is available.

Layouts

Layouts are the NHaml equivalent of master pages. NHaml provides a Rails-like layout system. Layouts are applied automatically based on the following conventions:

  1. If a layout is specified through the masterName argument of RenderView then that layout is applied. Or,
  2. If a layout with the same name as the controller exists in Views/Shared then it is applied. Or,
  3. If a layout called Application.haml exists in the Views/Shared folder then it is applied.

Here is an example layout targeting the Products controller (Views/Shared/Products.haml)

~/Views/Products/Products.haml

!!!
%html{xmlns="http://www.w3.org/1999/xhtml"}
  %head
    %title My Sample MVC Application
    %link{href="../../Content/Sites", rel="stylesheet", type="text/css"}
  %body
    #inner
      #header
        %h1 My Store Manager - Products Section
      #menu
        %ul
          %li
            %a{href="/"} Home
          %li
            = Html.ActionLink("About Us", "About", "Home")
          %li
            = Html.ActionLink("Products", new { Controller = "Products", Action = "Category", ID = 1 })
      #maincontent
        _
      #footer

A layout file uses the ’_’ partial operator with no arguments to signify where view content should be inserted into the layout.

Compilation Model

NHaml views are compiled. The first time an NHaml view is requested it is parsed and compiled into a .NET Type capable of rendering the view. This Type is then cached. The view engine can run in two modes: development or production. In development mode, the view engine will automatically recompile a cached view if any of it”s constituent haml files are modified. Production mode may be enabled through the web.config file like so:

<configuration>
    <configSections>
    <section name="nhamlViewEngine" 
             type="Mindscape.NHaml.ViewEngine.Configuration.NHamlViewEngineSection, Mindscape.NHaml.ViewEngine" />
  </configSections>
  <nhamlViewEngine production="true" />
</configuration>

ViewData & Helpers

NHaml views inherit from an NHamlView base class that makes available the standard ASP.NET MVC helpers: AjaxHelper, HtmlHelper and UrlHelper along with a
ViewData property. These can be accessed and used in the same way as per the Web Forms view engine. For example,

%li
  = Html.ActionLink("About Us", "About", "Home")

results in:

<li>
  <a href="/Home/About">About Us</a>
</li>

NHaml Language Reference

Disclaimer: Most of this reference was lifted from the main Haml site.

Tags %

The ’% character is placed at the beginning of a line. It‘s followed immediately by the name of an element, then optionally by modifiers (see below), a space, and text to be rendered inside the element. It creates an element in the form of <element></element>. For example:

%one
  %two
    %three Hey there

is compiled to:

<one>
  <two>
    <three>Hey there</three>
  </two>
</one>

Any string is a valid element name; NHaml will automatically generate opening and closing tags for any element.

Attributes {}

Braces represent a C# 3 anonymous type object initializer statement that is used for specifying the attributes of an element. It is evaluated as an anonymous type, so
logic will work in it and local variables may be used. The braces are placed after the tag is defined. For example:

%head
  %title My Sample MVC Application
  %link{ href="../../Content/Sites", rel="stylesheet", type="text/css" }

is compiled to:

<head>
  <title>My Sample MVC Application</title>
  <link href="../../Content/Site.css" rel="stylesheet" type="text/css" />
</head>

Self-closing Tags /

The ’/’ character, when placed at the end of a tag definition, causes the tag to be self-closed. For example:

%br/
%meta{ http_equiv" = "Content-Type", content = "text/html"}/

is compiled to:

<br />
<meta http-equiv="Content-Type" content="text/html" />

Some tags are automatically closed, as long as they have no content. meta, img, link, script, br, input and hr tags are closed by default.

%br
%meta{ http_equiv = "Content-Type", content = "text/html" }

is also compiled to:

<br />
<meta http-equiv="Content-Type" content="text/html" />

Class and Id . and #

The ’.’ and ’#’ are borrowed from CSS. They are used as shortcuts to specify the class and id attributes of an element, respectively. Multiple class names can be specified in a similar way to CSS, by chaining the class names together with periods. They are placed immediately after the tag and before an attributes hash. For example:

%div#things
  %span#rice Chicken Fried
  %p.beans{ food = "true" } The magical fruit
  %h1.class.otherclass#id La La La

is compiled to:

<div id="things">
  <span id="rice">Chicken Fried</span>
  <p class="beans" food="true">The magical fruit</p>
  <h1 class="class otherclass" id="id">La La La</h1>
</div>

And,

#content
  .articles
    .article.title
      Doogie Howser Comes Out
    .article.date
      2006-11-05
    .article.entry
      Neil Patrick Harris would like to dispel any rumors that he is straight

is compiled to:

<div id="content">
  <div class="articles">
    <div class="article title">Doogie Howser Comes Out</div>
    <div class="article date">2006-11-05</div>
    <div class="article entry">
      Neil Patrick Harris would like to dispel any rumors that he is straight
    </div>
  </div>
</div>

Implicit Div Elements

Because the div element is used so often, it is the default element. If you only define a class and/or id using the . or # syntax, a div element is automatically
used. For example:

#collection
  .item
    .description What a cool item!

is the same as:

%div{ id = "collection" }
  %div{ class = "item" }
    %div{ class = "description" } What a cool item!

and is compiled to:

<div id="collection">
  <div class="item">
    <div class="description">What a cool item!</div>
  </div>
</div>

Evaluate C# Output =

’=’ is placed at the end of a tag definition, after class, id, and attribute declarations. It‘s just a shortcut for inserting C# code into an element. It works the same as = without a tag: it inserts the result of the C# code into the template.

%p= string.Join(" ", new string[]{"He", "braid", "runner!"})

Results in:

<p>He braid runner!</p>

No Special Character

If no special character appears at the beginning of a line, the line is rendered as plain text. For example:

%gee
  %whiz
    Wow this is cool!

is compiled to:

<gee>
  <whiz>
    Wow this is cool!
  </whiz>
</gee>

DOCTYPES !!!

When describing XHTML documents with NHaml, you can have a document type or XML prolog generated automatically by including the characters !!!. For example:

!!! XML
!!!
%html
  %head
    %title Myspace
  %body
    %h1 I am the international space station
    %p Sign my guestbook

is compiled to:

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
  <head>
    <title>Myspace</title>
  </head>
  <body>
    <h1>I am the international space station</h1>
    <p>Sign my guestbook</p>
  </body>
</html>

You can also specify the version and type of XHTML after the !!!. XHTML 1.0 Strict, Transitional, and Frameset and XHTML 1.1 are supported. The default version is 1.0 and the default type is Transitional. For example:

!!! 1.1

is compiled to:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

and

!!! Strict

is compiled to:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

If you‘re not using the UTF-8 characterset for your document, you can specify which encoding should appear in the XML prolog in a similar way. For example:

!!! XML iso-8859-1

is compiled to:

<?xml version="1.0" encoding="iso-8859-1" ?>

XHTML Comments /

The ’/’ character, when placed at the beginning of a line, wraps all text after it in an HTML comment. For example:

%billabong
  / This is the billabong element
  I like billabongs!

is compiled to:

<billabong>
  <!-- This is the billabong element -->
  I like billabongs!
</billabong>

The forward slash can also wrap indented sections of code. For example:

/
  %p This doesn"t render...
  %div
    %h1 Because it"s commented out!

is compiled to:

<!--
  <p>
This doesn"t render...</p>
  <div>
    <h1>Because it"s commented out!</h1>
  </div>
-->

You can also use Internet Explorer conditional comments (about) by enclosing the condition in square brackets after the /. For example:

/[if IE]
  %a{ :href = "http://www.mozilla.com/en-US/firefox/" }
    %h1 Get Firefox

is compiled to:

<!--[if IE]>

  <a href="http://www.mozilla.com/en-US/firefox/">
    <h1>Get Firefox</h1>
  </a>
<![endif]-->

Escape Sequence \

The backslash character escapes the first character of a line, allowing use of otherwise interpreted characters as plain text. For example:

%title
  = @title
  \- MySite

is compiled to:

<title>
  MyPage
  - MySite
</title>

Line Continuation |

The pipe character designates a multiline string. It‘s placed at the end of a line and means that all following lines that end with | will be evaluated as though they were on the same line. For example:

%whoo
  %hoo I think this might get |
    pretty long so I should |
    probably make it |
    multiline so it doesn"t |
    look awful. |
  %p This is short.

is compiled to:

<whoo>
  <hoo>
    I think this might get pretty long so I should probably make it multiline so it doesn"t look awful.
  </hoo>
  <p>This is short</p>
</whoo>

Partials & Layouts _

Use an ’_’ to render a partial or the content of a layout. For a partial, specify the name of the partial after the underscore like so:

%p
  _ Customer

will render the _Customer.haml partial file.

An ’_’ on it”s own is used to specify where the content within a layout will be inserted:

%p
  _

Evaluate Output =

The ’=’ character is followed by C# code, which is evaluated and the output inserted into the document as plain text. For example:

%p
  = "hi" + " there" + " reader!" 
  = "yo"

is compiled to:

<p>
  hi there reader!
  yo
</p>

Evaluate Silent -

The ’-’ character makes the text following it into “silent” code: C# code that is evaluated, but not output.

It is not recommended that you use this widely; almost all processing code and logic should be restricted to the Controller, Helpers, or partials.

For example:

- string foo = "hello" 
- foo += " there" 
- foo += " you!" 
%p= foo

is compiled to:

<p>
  hello there you!
</p>

Code Blocks

C# code blocks, like XHTML tags, don‘t need to be explicitly closed in NHaml. Rather, they‘re automatically closed, based on indentation. A block begins whenever the indentation is increased after a silent script command. It ends when the indentation decreases.

- for (int i=42; i<47; i++)
  %p= i
%p See, I can count!

is compiled to:

<p>
  42
</p>
<p>
  43
</p>
<p>
  44
</p>
<p>
  45
</p>
<p>
  46
</p>
<p>See, I can count!</p>

Silent Comments -//

The hyphen followed immediately by a C# comment has the effect of a silent comment. Any text following this isn‘t rendered in the resulting document at all.

For example:

%p foo 
  -// This is a comment %p bar

is compiled to:

<p>
  foo
</p>
Trackbacks

Use this link to trackback from your own site.

Comments

Leave a response

  1. Wed, 19 Dec 2007 03:34:20 CST

    Introducing NHaml - An ASP.NET MVC View Engine…

    You’ve been kicked (a good thing) - Trackback from DotNetKicks.com…

  2. Wed, 19 Dec 2007 03:44:04 CST

    […] Original post by Andrew […]

  3. Jacques Philip Wed, 19 Dec 2007 13:01:04 CST

    Very nice, thank you.
    This seems very wrist friendly.

  4. Jesse Wed, 19 Dec 2007 13:24:57 CST

    What if I dont want to use xhtml but HTML 4.01. My front end dev has a whole slew of reasons why he doesnt like xhtml(Don’t even get him started). So can I generate a doctype like this:

  5. Jesse Wed, 19 Dec 2007 13:26:13 CST

    I guess the doctype tag got stripped above. sorry.

    DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01//EN” “http://www.w3.org/TR/html4/strict.dtd”

  6. Neal Wed, 19 Dec 2007 14:15:37 CST

    Very cool AP. Pity I can’t inflict this on my designer just yet (although she took to MonoRail like the proverbial duck so there is hope) =)

  7. Wed, 19 Dec 2007 15:07:54 CST

    Nice work :) I know Peter B was looking for just thus very thing a while ago … hopefully I’ll get some time to take it for a test drive!

  8. Andrew Wed, 19 Dec 2007 15:41:45 CST

    @Jesse - I’ll look at making this change.

    @Jacques, @Neal, @Alex - Thanks!

  9. Wed, 19 Dec 2007 16:23:08 CST

    And another view engine for ASP.NET MVC has been born…

    And another view engine for ASP.NET MVC has been born…

  10. Jacques Philip Wed, 19 Dec 2007 16:26:15 CST

    I was able to compile with C# express as I could not download VS yet (Too big)
    I noticed that the hard coded path for the style sheet and home link to not work when you run the application under a virtual path.
    Using:
    %a{href=Html.ResolveUrl(”~/”)} Home for the home link seems to work better
    I think there is a bug in ResolveUrl though, the the stylesheet link, I had to use a double’/’ like this:
    %link{href=Html.ResolveUrl(”~//Content/Site.css”), rel=”stylesheet”, type=”text/css”}

    Do you know of a better editor than VS to edit the views?
    The indentation is not very obvious, maybe a Python or Ruby editor?

  11. Andrew Wed, 19 Dec 2007 16:32:28 CST

    Hi Jacques,

    Yeah, the test app is just a clone of Scott Gu’s MVC sample - I’ll take a look at ironing out any wrinkles.

    For editing make sure you configure you’re editor to use 2 spaces instead of tabs for haml files. You could try SciTE, Notepad++, Notepad2 or maybe the e text editor.

    Cheers,

    Andrew.

  12. Wed, 19 Dec 2007 16:54:38 CST

    This is sweet man! Why not put it up on google code or codeplex?

  13. Andrew Wed, 19 Dec 2007 17:55:15 CST

    I’m creating a google project for it as we speak :-)

  14. liviu Wed, 19 Dec 2007 17:55:54 CST

    Back to BRAIL horror. What use has a language that has no support in the ide? Where is intellisense?
    Common guys…

  15. Wed, 19 Dec 2007 18:06:21 CST

    […] Andrew has created a rather lengthy blog post about the engine as well as how to write in Haml, Check out the NHaml View Engine here. […]

  16. Jacques Philip Wed, 19 Dec 2007 18:23:59 CST

    Found a syntax highlighter for Vim, screen shot here:

    It seems to works with your implementation with minor modifications.

  17. Andrew Wed, 19 Dec 2007 18:34:15 CST

    Cool, there is also one for Textmate that targets Rails.

  18. Wed, 19 Dec 2007 23:25:03 CST

    […] Peter has created NHaml, a new view engine for MS MVC based on the ruby Haml dsl. Sweet!! Maybe we can get Andrew to drop […]

  19. Wed, 19 Dec 2007 23:30:16 CST

    Any thoughts about putting this in the MVC Contrib project? We would love to have it.

  20. Thu, 20 Dec 2007 01:40:30 CST

    Very cool! Noticed one minor quibble in one of the examples.
    Should

    <span id=”rice”>Chicken Fried

    Have been

    <span id=”rice”>Chicken Fried</span>
    ?

  21. Andrew Thu, 20 Dec 2007 02:17:26 CST

    @Haacked,

    Thanks, I’ve fixed this now.

  22. Andrew Thu, 20 Dec 2007 02:22:59 CST

    @Jesse,

    I’ve added the HTML 4.01 doc types. You use them like this:

    !!! HTML
    !!! HTML Strict
    !!! HTML Frameset

    Grab the source here:

  23. Jacques Philip Thu, 20 Dec 2007 03:08:00 CST

    Do you plan on porting Sass too?
    I guess one could use Ruby to compile Sass templates manually in an ASP.NET MVC site.

  24. Andrew Thu, 20 Dec 2007 03:20:26 CST

    No plans at this stage.

    Yep, you could definitely do that.

  25. michaud Thu, 20 Dec 2007 09:33:18 CST

    Yeeeees, but why… It just adds an other level of complexity. And its another chain piece where it can break.
    It looks more like a nice ‘hypothetical’ project: Yes it can be done.

    And these kinds of this will be overshadowed by the new MVC controls that probably will be added to the namespace.

  26. Stu Thu, 20 Dec 2007 11:38:18 CST

    This looks fantastic. Good stuff.

  27. Andrew Thu, 20 Dec 2007 15:33:49 CST

    @michaud,

    How is this another level of complexity when you are substituting one view engine for another? I suspect Web Forms has an order of magnitude more moving parts than NHaml.

    “new MVC controls”? I think you’re missing the big picture. ASP.NET MVC is about laying a solid architectural foundation - not about building more controls.

  28. Thu, 20 Dec 2007 16:21:27 CST

    Hey Andrew,
    I’d like to discuss your thoughts on incorporating the NHaml view engine into the MVC Contrib project. Can you shoot me an email so I can make my pitch?

    -Bill

  29. Jacques Philip Thu, 20 Dec 2007 20:05:37 CST

    Hi Andrew,

    I got Sass to work with 5 lines of ruby code.
    I could not make it work with IronRuby though.
    It is really a nice complement to NHaml as the structure of the Sass files parallels the one of the NHaml views.
    It can also compile multiple sass files into a single compacted css file and it can be run as post-build event.

  30. Thu, 20 Dec 2007 22:07:56 CST

    Resumo da semana natalino…

    Resumo da semana natalino…

  31. Fri, 21 Dec 2007 11:34:38 CST

    This is really a cool thing, I mean, having a new way of designing HTML pages but good only for the few developers that are building also the presentation side of web apps.
    I don’t think could be a good replacement of the old HTML used by all the designers around the world.

  32. Sergio Pereira Sun, 23 Dec 2007 18:16:42 CST

    Nicely done.
    Which assemblies and namespaces are included in the compilation? The same ones as the webforms engine (i.e. defined in the web.config if needed) ?
    I’m just trying to make sure we will have extension methods and any other custom code available in the templates.

  33. Mon, 24 Dec 2007 06:50:06 CST

    […] man z.B. die Routingfunktionalitäten oder auch die View-Engine ändern bzw. ersetzen kann. Mit NHaml ist eine weitere View Engine am […]

  34. Wed, 26 Dec 2007 00:51:12 CST

    New view engines in the MvcContrib project for asp.net mvc…

    New view engines in the MvcContrib project for asp.net mvc…

  35. Andrew Wed, 26 Dec 2007 17:19:41 CST

    @Sergio,

    The references are:

    mscorlib, System, System.Core, Mindscape.NHaml, Mindscape.NHaml.ViewEngine, System.Web.Extensions, System.Data.Linq, MVCToolkit

    The namespaces are:

    System, System.Text, Mindscape.NHaml, Mindscape.NHaml.Utilities, System.Web, System.Web.Mvc, Mindscape.NHaml.ViewEngine;

    These are currently only configurable in code (NHamlViewFactory.cs) but feel free to submit a patch :-)

    Cheers,

    Andrew.

  36. AndrewM Thu, 27 Dec 2007 07:28:09 CST

    What is the reason to use spaces instead of tabs for indentations? I’m not against spaces but tabs are just more suitable IMO.

  37. Greg Banister Fri, 28 Dec 2007 12:42:34 CST

    Andrew,
    First of all, Great Work!
    I may have found a bug. If there is a hyphen in the path to a view then that hyphen gets invlided in the generated class name for the view (which is invalid syntax).
    I’ve created a failing test in:

    [Test]
    public void
    Should_replace_hyphens_with_underscores_in_classnames_for_a_view()
    {
    string className = TemplateCompiler.MakeClassName(”C:\\test-path\\Views\\Test\\Test.haml”);
    Assert.AreEqual(”C__test_path_Views_Test_Test_haml”,className);
    }

    (I needed to make MakeClassName public to facilitate testability)

    I then made this test pass by changing the regex in _pathCleaner to [-/\\/\.:\s]

    Greg

  38. Andrew Sat, 29 Dec 2007 02:09:01 CST

    AndrewM,

    2 spaces is the standard used by Rails and Haml and is also my preferred approach.

    We can probably make this configurable.

    Cheers,

    Andrew.

  39. Andrew Sat, 29 Dec 2007 02:11:38 CST

    Greg,

    Good work. I’m in the process of moving the project to MVC Contrib so I’ll fix it there soon.

    Cheers,

    Andrew.

  40. AndrewM Sat, 29 Dec 2007 07:11:11 CST

    >> 2 spaces is the standard used by Rails and Haml and is also >> my preferred approach.

    >> We can probably make this configurable.

    That would be great! Thx.

  41. AndrewM Sat, 29 Dec 2007 09:26:56 CST

    I’ve found little problem in file CompiledView.cs:
    private void CompileView(object viewData)
    {
    string viewDataType = “System.Web.Mvc.ViewData”;
    if(!NHamlViewFactory.ViewDataIsDictionary(viewData))
    {
    _templateCompiler.AddReference(viewData.GetType().Assembly.Location);
    ………
    This code adds reference to assembly, which contains type of value, passed in ViewData. But there is compilation error appears, if passed type has reference to another type, which is declared in other assembly - “The type ” is defined in an assembly that is not referenced.”

  42. Andrew Sat, 29 Dec 2007 17:14:25 CST

    AndrewM,

    Custom references can be added in code (NHamlViewFactory.cs static ctor). This will be configurable in web.config soon.

    Cheers,

    Andrew.

  43. mike kidder Tue, 01 Jan 2008 04:21:27 CST

    I get an error on your TestApp, it cannot compile the Index.haml, indicating there are invalid tokens.

  44. Andrew Tue, 01 Jan 2008 06:24:39 CST

    Hi Mike,

    This is probably the same error raised by Greg Banister above. The error has been fixed in the trunk here:

    Cheers,

    Andrew.

  45. Gabe Fri, 04 Jan 2008 18:17:13 CST

    Is it possible to render partials that are in other Controller folders and/or Shared?

    Is it possible to pass values to the partial? For instance, my partial does what was previously a postback and I would like to be able to process some stuff by the controller that it posts to and then redirect to the original controller/action.

    Thanks.

  46. Gabe Fri, 04 Jan 2008 18:17:48 CST

    Oops forgot something, THANK YOU VERY MUCH!!! I have missed HAML since I started ASP.NET :)

  47. Sat, 05 Jan 2008 01:37:38 CST

    2008 第一帖:asp.net mvc相关开源项目推荐…

    asp.net mvc ctp版本发布不到一个月时间,在社区出现了丛多的优秀开源项目,社区的活跃性非常高哦,前一段时间园子里也引发了MVC和WebForm的讨论,现在给各位推荐几个相关的优秀项目,这些…

  48. Andrew Mon, 07 Jan 2008 01:56:03 CST

    Gabe,

    NHaml is now part of MVC Contrib. Please feel free to create a feature request on CodePlex or better yet submit a patch :-)

    Cheers,

    Andrew.

  49. Mon, 07 Jan 2008 15:19:18 CST

    Architecture Chat #22 This Thursday…

  50. Peter Mon, 21 Jan 2008 15:18:35 CST

    Sorry I really don’t see the point of this. I’d have to see some hard stats that this really does improve anything.

  51. Thu, 24 Jan 2008 19:31:34 CST

    I love it.

  52. Thu, 24 Jan 2008 19:57:09 CST

    […] language and HAML… (Note to self, write HAML view factory for ASP.NET MVC. UPDATE: Crap! The brilliant Andrew Peters made NHAML this last month and added it to MVC Contrib. New Note to self, crush Andrew Peters for being too awesome.) […]

  53. Fri, 25 Jan 2008 10:52:14 CST

    NHaml for Sitecore?…

  54. Fri, 25 Jan 2008 15:16:56 CST

    NHaml for Sitecore?…

    “Haml is a markup language that‘s used to cleanly and simply describe the XHTML of any web document,…

  55. John Mon, 28 Jan 2008 08:30:55 CST

    Does it work with VB?

  56. Mon, 28 Jan 2008 10:18:58 CST

    […] Introducing NHaml - An ASP.NET MVC View Engine […]

  57. Andrew Mon, 28 Jan 2008 16:17:25 CST

    @Scott,

    Thanks!

    @John,

    Not currently. It _should_ be possible however. We would need to make the compilation system pluggable. We’d love to see that patch! :-)

  58. Tue, 29 Jan 2008 15:22:05 CST

    The script tag should not be automatically closed. Since that does is not supported by some browsers.

  59. Andrew Tue, 29 Jan 2008 15:42:06 CST

    That is fixed in the trunk at:

  60. d8v15 Mon, 04 Feb 2008 22:26:53 CST

    Is this only for VS 2008? Im on 2005, and cant run any test application.

  61. Bryan Ross Tue, 19 Feb 2008 14:09:39 CST

    I’m gonna go ahead and second the request for SASS. I’ve been doing some work with haml and sass using PHP (yuck) for a while now, and since I’m pretty much a closet python freak, it’s a breath of fresh air to work with HAML and SASS. Hell, CSS constants and color math are worth it ALONE.

  62. Tue, 26 Feb 2008 13:37:13 CST

    […] will be used for persistence, Castle Windsor for dependency injection, NUnit and NMock for testing, NHaml for the views, and principles from agile, domain-driven design, and test-driven development will be […]

  63. Wed, 27 Feb 2008 02:14:07 CST

    […] want to use NHaml instead af that annoying ASPX thing to render our views. If you are unfamiliar with NHaml, I can […]

  64. Fri, 29 Feb 2008 09:58:41 CST

    […] three that I’ve looked at so far have been the standard ASP.NET WebForms, NVelocity and NHaml. I kinda like what I see in NVelocity and NHaml, but the documentation and support appears to be a […]

  65. Jonas Gauffin Tue, 25 Mar 2008 08:19:33 CDT

    I’m interested using haml in a .net 2.0 project (without asp).
    I can’t really figure out how to just use the lib.

  66. Mon, 07 Apr 2008 11:34:31 CDT

    […] NHAML […]

  67. Igor Loginov Fri, 18 Apr 2008 11:38:23 CDT

    Andrew,

    Great work, thank you! Eager to see final release of ASP.NET MVC and Contrib package!

    I’d rather repeat Jonas’ question: how could I use NHaml template engine outside MVC?

  68. admin Sat, 19 Apr 2008 20:47:13 CDT

    Igor,

    I just posted about how to use NHaml standalone: https://andrewpeters.net/2008/04/19/standalone-nhaml/

    Cheers,

    Andrew.

  69. Veri Sun, 27 Apr 2008 14:53:33 CDT

    There is a handler for Sass like files on CodePlex. I didn’t use it but it seems like it can handle very basic parsing functionality.

  70. Gavin Mon, 12 May 2008 17:49:56 CDT

    This is amazing!

    What is the syntax for getting a localized resource from a resx file (in the global resources folder for example?)

    For example, with the webform engine, I would say: Resources.Language.MyString (for example). With this view engine I get a “Resources cannot be found” exception.

    Thank you!!

  71. Brandon Thu, 15 May 2008 00:08:48 CDT

    Pretty nice, Andrew!

    I’m wondering though… in your layout file example, you have:

    %link{href=”../../Content/Sites”, rel=”stylesheet”, type=”text/css”}

    … which would only work intermittently, wouldn’t it?

    It’d be fine for /Home/Index/, but wouldn’t /Home/ end up unstyled?

    During development, my URL’s are like: /Project/Home/About, and in production, they’re just /Home/About … so I can’t use absolute URLs for these things…

    Any ideas?

  72. Tue, 20 May 2008 14:57:29 CDT

    […] NHamlStringTemplate NVelocity and here […]

  73. Mon, 02 Jun 2008 12:23:55 CDT

    […] Sergey has announced NHAML for Monorail. Andrew Peters brough NHAML to ASP.NET MVC last year, and now us Monorail users can enjoy using a very different kind of templating engine to […]

  74. david Sun, 08 Jun 2008 13:49:54 CDT

    Andrew I am having issues with rendering the nhaml website in iis. Its working in cassini perfectly ? any experience with iis

  75. Andrew Sun, 08 Jun 2008 17:01:37 CDT

    David,

    Not personally. Try posting your question here:

    Cheers,

    Andrew.

  76. Jessica Hamilton Tue, 24 Jun 2008 18:08:44 CDT

    It looks nice, haven’t tried it yet, but will very shortly! JD keeps prodding me to do it :P

    Two comments: in the first example, you don’t generate the exact same HTML - you’re missing () around an section.

    Secondly, I guess this is inherited from haml, but the use of the | for multiline strings is, IMO, a horrible convention.

    I think using a double-indent, i.e. 4 spaces would do the trick, assuming you have a strict parser.

    Jessica :)

  77. Mon, 30 Jun 2008 17:17:09 CDT

    […] tried the NHaml view engine, a .NET implementation of the Rails Haml view engine. My NHaml default layout (master […]

Comments