Spark View Engine

This week I am continuing my exploration of view engines by taking a closer look at the Spark view engine. I wanted to find at least one third party view engine that I could play around with and Spark seemed like potentially the best candidate. Spark was released before Razor, and it appears that it was last updated in June 2015. The good news is that there is a NuGet Package that allows you to use Spark with MVC 5. This helps to make it at least usable with current versions of Visual Studio.

One of the primary goals with Spark is that HTML comes to the forefront in the markup with less intermixed code than was seen with the ASPX view engine. Part of the driving force behind this implementation was that ASPX pages would be more and more difficult to maintain and read as time went by and they grew in size. The view engine was authored by Louis Dejardin and based on comments and search results, I’m going to guess that it was at one time the most popular third party view engine.

In my most recent post, I mentioned refreshing a classic ASP.NET tutorial web application, the Movie App. I had brought this project up to speed using MVC 5, so that I could use it as a basis for other experiments. I figured that a perfect usage for this would be to convert my previously created version of the Movie App to leverage the Spark view engine.

Getting up and running with Spark was not too tough. I started out by referencing the previously mentioned Spark.Web.Mvc5 NuGet package. After that, I updated my Global.asax.cs, removing all other view engines from usage and adding the Spark view engine. This would be the approach that you would want to take if you were wanting to using only Spark. If you wanted to also use Razor or ASPX, you would not bother to clear out the existing view engines.

As an optional step, you can add a spark section to your Web.config. Take a look at the configuration documentation for more details on what you can do there. I did read that setting the debug setting to true can be helpful in troubleshooting view compilation errors, so you may want to consider using that setting.

After modifying the configuration, I needed to make a few changes to the file structure under the Views folder. First, I had to rename all the views to *.spark, so that they would be recognized by the Spark view engine. Second, I deleted _ViewStart.cshtml, as it is not used by Spark. Third, I renamed _Layout.cshtml to Application.spark. Spark automatically looks for a layout file by that name. Finally, I had to add a reference to System.Web.Optimization in the _global.spark file that was added when I referenced the NuGet package. This enabled me to reference Styles.Render and Scripts.Render.

The next step, and the most involved step, was to replace the existing Razor syntax in all of the views with Spark syntax. One of the things that pops out at you right away is that several of the C# constructs, such as if and for are replaced by markup that looks like HTML. This does contribute to the readability of the document. Below is one example of a view that I updated, the movie creation view.

The Form tag in the above example leverages another important feature of Spark, bindings. You can create a binding that will replace HTML-like markup with C# code. In this case, I created a binding that could wrap some HTML with the appropriate code needed to render a form. This binding is defined within Bindings.xml, which sits in the Views folder. Below is the example binding that I created.

After setting up the binding and replacing the existing Razor syntax in the views, I was pretty much set to go. With a minimal amount of effort, I once again had the Movie App running, but this time using Spark syntax. Despite the fact that Spark hasn’t been updated in several years, it is still a fairly painless experience to get started.

Would I choose to use Spark over Razor? Probably not. I’ve already got some amount of Razor experience and I didn’t see anything compelling enough to persuade me to change. However, it is nice to know that you have options, and I can see how Spark was an attractive alternative to ASPX. The HTML-like markup does make it easier to read than a complex ASPX view.

Third Party View Engines R.I.P?

After finishing my recent overview of ASP.NET MVC view engines, I thought that I would take a deeper look at a specific third party view engine implementation. The users of Stack Overflow have provided a good list of available view engines. I took a brief look at the web sites for all of the view engines, and one thing that really stuck out at me was the fact that none of them had been updated for quite some time.

Despite this, I decided that I would experiment one of them, and chose NHaml. Based on the Rails Haml view engine, NHaml sounds intriguing to me. It takes a different approach than most by abstracting away the HTML markup language.

I saw that a NuGet package was available for NHaml, so i figured that chances for getting it running were promising. Unfortunately, after fiddling around with it for a while, I did not have good luck getting it running under MVC5. I managed to get around the initial error with the NuGet package (Derived types must either match the security accessibility of the base type or be less accessible) by downloading the source code and removing the “AllowPartiallyTrustedCallers” attribute from the SharedAssemblyInfo.cs in the System.Web.NHaml project. However, I then found myself running into access denied errors as NHaml apparently tries to delete temp files from disk.

Considering that NHaml has not been updated for quite some time, I decided that it wasn’t worth investing anymore time into getting it up and running. I may still take a look at one of the other view engines, just to get a sense for how different it is from Razor.

I do still wonder why there has been no recent action on the third party view engine front. I don’t have any complaints about Razor, but is it really that good that it deserves no well maintained competition other than the ASPX view engine? Apparently, Microsoft has done a good job of meeting the desires of developers with the feature set that they have provided in Razor.

View Engines

ASP.NET MVC is a pluggable framework with many parts that may be replaced or customized. One of these parts is the view engine. View engines assist controllers with transforming views into HTML. The view engine is a part of the ASP.NET MVC pipeline. A detailed diagram of the pipeline can be found at DotNetTricks.

MVC includes support for two default view engines. The ASPX view engine was the default for MVC 1.0 and 2.0. This is the view engine that is used by Web Forms. The Razor view engine became the default starting with MVC 3.0. This view engine leveraged a new syntax that relies heavily on the @ character. Even though the Razor view engine has been the default for more recent versions of MVC, you can still use ASPX, and both are enabled by default for an MVC project. MVC additionally allows you to disable one or both of these default view engines and enable other third party view engines such as Spark and NHaml.

You can create your own custom view engine, which is a powerful feature offered by MVC. There are three main components necessary for this: a class that implements IViewEngine, a class that implements IView, and views that leverage your custom view engine markup. After doing all of this, you will need to add your view engine (the class that implements IViewEngine) to the list of view engines in the Application_Start method of Global.asax.cs. When experimenting with view engines, I followed along with a fine example from Code Project.

When creating a class that implements IViewEngine, you can inherit from the VirtualPathProviderViewEngine, which provides some of the default behavior for you. One of the key things that you will want to accomplish with this class is to specify the location of your views. If you will still be using one or both of the default view engines alongside your custom view engine, you will need to be careful to specify a unique location or different file extension for your custom views, so that they will not be mistaken for Razor or ASPX views. Below is an example of how to specify the view location within the constructor of the class implementing IViewEngine. It searches for templates in the default location, but with the .tmpl extension.

The class that implements IView is where a lot of the action takes place. It is here that you will need to provide your special template parsing logic. The job of this code will be to find a given markup and replace it with something else. In my case, I was looking for markup like “<TMPL_VAR NAME=Message>” and replacing it with the “Message” value within ViewData. I replaced the Parse method from the Code Project example with the following.

You will of course be providing a number of views that match the format that your IView class is looking for. Below is an example of what I did in my view while experimenting with view engines. This is a very rudimentary example, but it did serve to demonstrate how to implement a custom view engine.

Why would you want to use a custom view engine? Based on the search results that I found, the most frequent reason that people seem to use a custom view engine is to provide different locations to look for views. Basically, they are wanting to organize their file structure differently than the default. Another reason that you might want to implement a custom view engine is if you are particularly fond of a templating engine used in another language and you want to implement your own version for ASP.NET. This is essentially what I was doing for my example. Before working with .NET, I came from a Perl background. The examples above were the beginnings of implementing a view engine that mimiced the functionality of Perl’s HTML::Template templating engine. Implementing a templating engine from another language could be useful if you have a lot of developers that are not familiar with Razor, but are familiar with another templating engine. However, there may be a price to pay when bringing new .NET developers onboard who are already familiar with Razor. Perhaps a more likely scenario for implementing your own view engine would be to provide some functionality that makes you more productive or does something that Razor cannot do.

Regardless of your motives, one must admit that it is impressive that Microsoft offers the opportunity to customizing this aspect of the pipeline. It provides one with a great deal of power and flexibility. Although I don’t know how useful this feature will be in my own future projects, I am curious to take a peek at some of the other view engines to see how they compare and contrast to the default view engines.