I did a little looking around at alternative view engines for ASP.NET MVC 2 and gave Spark a go.  My biggest problem is that its not Haml.  I was moving some *.aspx views over to *.spark and pretty much its an exercise in replacing <% with { with some XMLish <if> blocks thrown in.  (Didn’t we already determine that XML if’s are bad?)

Anyway decided not to use it but I did sort out a problem with 1.1.0.0 (as of November 2010) where ASP.NET MVC 2 Areas simply did not work with the view engine.  I suspect this is also the same reason why NHaml doesn’t work with Areas as well.

In the source for Spark in the Spark.Web.Mvc assembly within the DefaultDescriptorBuilder class around line 183 I’ve replaced the methods PotentialViewLocations, PotentialMasterLocations and PotentialDefaultMasterLocations with the following code:

 

protected virtual IEnumerable<string> PotentialViewLocations(string controllerName, string viewName, IDictionary<string,object> extra)  
{
    if (extra.ContainsKey("area"))
    {
        return ApplyFilters(new[]
        {
        controllerName + "\\" + viewName + ".spark",
        "Shared\\" + viewName + ".spark",
        "~\\Areas\\" + extra["area"] + "\\Views\\Shared\\" + viewName + ".spark",
        "~\\Areas\\" + extra["area"] + "\\Views\\" + controllerName+ "\\" + viewName + ".spark"
        }, extra);
    }

    return ApplyFilters(new[]
    {
        controllerName + "\\" + viewName + ".spark",
        "Shared\\" + viewName + ".spark",
    }, extra);
}

protected virtual IEnumerable<string> PotentialMasterLocations(string masterName, IDictionary<string, object> extra)  
{
    if (extra.ContainsKey("area"))
    {
        return ApplyFilters(new[]
        {
            "~\\Areas\\" + extra["area"] + "\\Views\\Layouts\\" + masterName + ".spark",
            "~\\Areas\\" + extra["area"] + "\\Views\\Shared\\" + masterName + ".spark",
            "Layouts\\" + masterName + ".spark",
            "Shared\\" + masterName + ".spark"
        }, extra);
    }

    return ApplyFilters(new[]
    {
        "Layouts\\" + masterName + ".spark",
        "Shared\\" + masterName + ".spark"
    }, extra);
}

protected virtual IEnumerable<string> PotentialDefaultMasterLocations(string controllerName, IDictionary<string, object> extra)  
{
    if (extra.ContainsKey("area"))
    {
        return ApplyFilters(new[]
        {
            "~\\Areas\\" + extra["area"] + "\\Views\\Layouts\\" + controllerName + ".spark",
            "~\\Areas\\" + extra["area"] + "\\Views\\Shared\\" + controllerName + ".spark",
            "Layouts\\Application.spark",
            "Shared\\Application.spark"
        }, extra);
    }

    return ApplyFilters(new[]
    {
        "Layouts\\" + controllerName + ".spark",
        "Shared\\" + controllerName + ".spark",
        "Layouts\\Application.spark",
        "Shared\\Application.spark"
    }, extra);
}

 

This doesn’t work with Hanselman’s Mobile Device Capabilities ViewEngine out of the box, you’ll have to do more work for that.

If you don’t want to go through the legwork of patching Spark 1.1.0.0 I’ve zipped up a Release build of the relevant files from my patch.

I had to dig pretty deep for the original solution.