2LeggedSpider

Spark View Engine for ASP.NET MVC

Posted in ASPNETMVC, MVC by Sumit Thomas on January 5, 2010

There’s been a lot of buzz around the new View Engine for ASP.NET called Spark. Spark is an open-source ASP.NET ViewEngine developed by Louis DeJardin (Listen to the conversation between Scott Hanselman and Louis DeJardin to get some insights on Spark). Spark works for both Monorail and ASP.NET MVC supporting C#, VB, IronPython and IronRuby.

There are other ViewEngines already available as an alternative to the default ASP.NET MVC ViewEngine. Honestly I have not tried anyone of them and I surely don’t have any clue as to whether they are better or worse compared to Spark. Well, I just like everyone else decided to follow the buzz and try out Spark.

I decided to develop a simple RSS Reader using ASP.NET MVC and with Spark as its ViewEngine. I am using the Spark documentation as reference for my experiment.

Lets look at how a Spark View differs from the regular ASP.NET MVC View. Consider the following View which we are familiar with…

 <%@ Page Title="" Language="C#" Inherits="System.Web.Mvc.ViewPage<IEnumerable<Product>>" %>
 <% if (Model.Count() > 0)
   { %>
<% foreach (var product in Model)
   { %>
<li>
    <%= product.Name %>
</li>
<% } %>
<%}
   else
   {%>
<p>
    No products available</p>
<%} %>

The equivalent Spark View would be…

<viewdata products="IEnumerable[[Product]]"/>
<ul if="products.Any()">
  <li each="var p in products">${p.Name}</li>
</ul>
<else>
  <p>No products available</p>
</else>

As you can see it is much cleaner and readable than the regular View. Checkout the Spark syntax in detail. Spark makes is really simple to data bind HTML elements to objects from the Controller.

Configuring ASP.NET MVC Project to use Spark ViewEngine

With this background on Spark, lets jump straight in to the task of configuring a ASP.NET MVC Web application to use Spark as its default ViewEngine.

Step 1: Download the Spark binaries from here. Extract the zip file and locate the bin folder.

Step 2: Create a new ASP.NET MVC Web Application and add reference to the assemblies Spark.dll and Spark.Web.Mvc.dll

Spark reference

Step 3: Add Spark to the ViewEngine collection in the Application_Start section of Global.asax

        protected void Application_Start()
        {
            ViewEngines.Engines.Add(new SparkViewFactory());
            RegisterRoutes(RouteTable.Routes);
        }

Your application is now ready for Spark!

Step 4: You may also add the following configuration settings in your web.config

	<configSections>
		<section name="spark" type="Spark.Configuration.SparkSectionHandler, Spark"/>
	</configSections>
	<spark>
		<compilation debug="true"/>
		<pages automaticEncoding="true">
		<namespaces>
                <add namespace="System.Web.Mvc"/>
                <add namespace="System.Web.Mvc.Ajax"/>
                <add namespace="System.Web.Mvc.Html"/>
                <add namespace="System.Web.Routing"/>
                <add namespace="System.Linq"/>
                <add namespace="System.Collections.Generic"/>
		</namespaces>
		</pages>
	</spark>

Another way of providing the Spark Engine settings is by creating an instance of ISparkSettings and passing it to the constructor of SparkViewFactory…

protected void Application_Start(object sender, EventArgs e)
{
    var settings = new SparkSettings()
        .SetDebug(true)
        .AddNamespace("System.Web.Mvc")
        .AddNamespace("System.Web.Mvc.Ajax")
        .AddNamespace("System.Web.Mvc.Html")
        .AddNamespace("System.Web.Routing")
        .AddNamespace("System.Linq")
        .AddNamespace("System.Collections.Generic");

    ViewEngines.Engines.Add(new SparkViewFactory(settings));
}

Thats all you have to do in terms of setting up the MVC Web application to use Spark ViewEngine.

Spark View Layouts

So far we have only configured the application to use Spark ViewEngine. Spark Views have a different extension from the regular ASP.NET MVC Views and as we saw already, they have a different syntax as well. Spark Views have the extension .spark. The way Spark ViewEngine deals with Master pages is also different. Lets look at it…


Master Pages

Application.spark – This is the application wide Master page which will be used by the Spark Engine. It could be place in Views/Layouts folder or Views/Shared folder.

[ControllerName].spark – If you need to use a Master page for individual Controllers then you can create a spark file with the name of the Controller. For instance if you have a HomeController then Views/Layouts/Home.spark or Views/Shared/Home.spark would be Master page for that Controller.

Check the Selecting Layout section in Spark documentation for more details.


Partial Views or User Controls

Any partial view prefixed with an underscore can have its own tag in Spark. For instance if we have a Partial View _LogOnUserControl.spark then we can refer to it in the Spark View as <LogOnUserControl />. If you don’t like this convention then you can remove the underscore and refer to the Partial View as <use file=”LogOnUserControl” />

With these changes in place our Views layout will look like this…

Spark View Layout

Let’s look at the individual Spark Views as to how they differ from the regular Views that you get when you create a new ASP.NET MVC Web Application.


Application.spark (replaces Site.master)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title>
        <use content="title">Default title</use>
    </title>
    <link href="~/Content/Site.css" rel="stylesheet" type="text/css" />
</head>
<body>
    <div class="page">
        <div id="header">
            <div id="title">
                <h1>
                    My MVC Application</h1>
            </div>
            <div id="logindisplay">
                <LogOnUserControl" /> // or <use file="_LogOnUserControl" />
            </div>
            <div id="menucontainer">
                <ul id="menu">
                    <li>!{Html.ActionLink("Home", "Index", "Home")}</li>
                    <li>!{Html.ActionLink("About", "About", "Home")}</li>
                </ul>
            </div>
        </div>
        <div id="main">
            <use content="view" />
            <div id="footer">
            </div>
        </div>
    </div>
</body>
</html>

We can create Home.spark as well in the same manner.


Index.spark(replaces Index.aspx)

<content name="title">
       Home Page
</content>
<h2>
    ${ViewData["Message"]}</h2>
<p>
    To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">
        http://asp.net/mvc</a>.
</p>


_LogOnUserControl.spark(replaces LogOnUserControl.ascx)

<if condition="Request.IsAuthenticated">
    Welcome <b>${Context.User.Identity.Name}</b>!
    [ !{Html.ActionLink("Log Off", "LogOff", "Account")} ]
</if>
<else>
    [ !{Html.ActionLink("Log On", "LogOn", "Account")} ]
</else>

Run the application and you will see the usual ASP.NET MVC Web Application’s home page but rendered using Spark ViewEngine. From what I have seen so far Spark looks promising and would be a great alternative for those who feel the default ViewEngine forces them to go back to the classic ASP days. I haven’t completely gone through all the possibilities in Spark and would like do so in the next few days.

Share your thoughts on Spark or any other ViewEngines you may have used.
[tweetmeme style=”compact”]

Tagged with: , ,

links for 2010-01-04

Posted in Daily Links by Sumit Thomas on January 4, 2010

My Top 10 Tech moments in 2009

Posted in technology by Sumit Thomas on January 1, 2010

[tweetmeme style=”compact”]

10. The Satyam fraud

It was a bad start to the year for the Indian IT industry as the news of Satyam Computer Services’ Accounting Scandal started to emerge. The fraud of Rs.40 billion shocked the Indian corporate industry especially the investors and employees. Some of my friends in Satyam had a difficult time as they were desperate applying for jobs elsewhere. I am glad that the company is back on track after some good measures by the government.

9. HTC launches India’s first Android based phone

After Apple’s iPhone 3G, it was HTC’s turn to grab the attention of the Indian Mobile market. HTC launched its new touch screen phone powered by Google Andriod, HTC Magic. This is the first Android phone to hit the Indian market.

8. Steve Jobs back at work

He is a true inspiration to many people around the world and that includes me. In June 2009 he continued to inspire many as he returned back to work after 5 months following his liver transplant. When he delivered the keynote in his customary attire, he mentioned the word Twitter and the micro-blogging site was down with a 503 error for about 15 minutes. Good that Microsoft’s business was not 100% internet based 😉

7. Bing!

In May, 2009 Microsoft launched its decision engined coined Bing! Bing was a talking point for quite sometime at work and on Twitter. Bing was intended to do things differently from its competition(Google?) or even from Microsoft Live. Though it was far better than Live, it has not a reached a stage yet where it can be called a clear competition to Google. Bing is getting better and I can see better results compared to its early days.

6. Google Wave

The last time I saw everyone madly running after free invites was for GMail. In 2009 it was Google wave. Every techie I met had one question in mind – “Do you have any Google wave invites left?”. The requests continue even now in Facebook and through emails. Even without fully understanding what it is all about everyone was on the “Give me, give me” bandwagon. Those who got the invite saw their excitement turning in to confusion, including me. Google wave has a confusing interface and does take a long time to understand what it really does. But sure there are some powerful collaboration features that many people may find very useful in the long run.

5. Google Maps India launched driving directions

This was a huge time and fuel saver for me. Driving in Bangalore is maddening because of the traffic and it gets crazier when you get lost. Before Google Maps launched the driving directions, I always used to get lost in Bangalore, thanks to its bad sign boards, confusing roads and one ways. Nowadays I use Google maps in my Nokia N82 and it gives me an accurate direction most of the time. Google maps in India keeps getting better and hopefully will catch up to its US counterpart pretty soon.

4. Social networks and Twitter

Social networking was on the boom in 2009 with many people joining sites like Facebook and Twitter. Twitter has become one of the important social media tool. Everyone from newsreaders to politicians to writers, techies, companies etc. have their own Twitter handle to share and collect information from the masses. 2009 saw thousands of tweets spreading real-time information covering everything from the Indian Parliamentary Elections,the demise of Michael Jackson, casualties of Swine flu etc. etc.

2009 also saw a rise adaptation of single sign-on services from Google FriendConnect, Facebook Connect and Twitter connect. The power it has brought to the whole social networking arena is immense.

3. Google Chrome OS

Google announced its planned for Chrome OS and vision behind this venture. According to Google

Google Chrome OS is an open source, lightweight operating system that will initially be targeted at netbooks.

Chrome OS is expected to be out in the second half of 2010. This is exciting given the popularity of netbooks is on the rise.

2. ASP.NET MVC Released!

After working on the beta version for weeks and falling in love with it, this was a much awaited announcement for 2009. The announcements by Phil Haack and Scott Gu spread across the web development community like fire. It was a great start to the year for the ASP.NET community in particular! Kudos to the team who worked really hard to come out with the RC and the different releases thereafter.

ASP.NET MVC 1.0 Released, 2.0 Release

1. Windows 7

Definitely the hottest news of 2009 was the launch of Windows 7 on Oct 22nd. This was Microsoft’s best ever release in a decade. After its bad run with Vista, Microsoft had to come out with a OS that will win back its customers and take its grip on the OS market. Windows 7 did take care of the many issues with Vista and offered little more than its predecessor. Windows 7 is quite a relief to those who had to put with Vista.

Those were my top 10 tech moments in 2009, which was quite an eventful year. Hope this year turns out to be better and more exciting than last year. Happy News Year to you all! 🙂

Tagged with: ,

links for 2009-12-30

Posted in Daily Links by Sumit Thomas on December 30, 2009

Fun with jQuery clone() and animate()

Posted in CSS, jquery by Sumit Thomas on December 29, 2009

[tweetmeme]While going through the jQuery API documention, I realised that I have not tried my hands at many of its wonderful functions. So I thought of doing something creative with clone() and animate() functions. Here are the list of things I am going to do…

  1. Capture the user’s keypress event as they type and get the key value
  2. Create a clone of a hidden DIV element and change its text to the keypress value
  3. Place the new DIV elements one after the other and provide some random background color for each DIV element
  4. Provide a touch of animation to make it look nice 🙂

OK, here we go…

First lets create a simple CSS class for our DIV element.

        .letter
        {
            font-weight: bold;
            color: #fff;
            border: 1px solid #000;
            padding: 5px;
            width: 20px;
            height: 20px;
            left: 0;
            float: left;
        }

This will create a simple box of dimension 20 x 20 pixels with a black border.

Next, we will jump in to the jQuery code…

        var newDiv = ""; 
        var oldDiv = "";
        $(document).ready(function() {
            oldDiv = $("div.letter");
            oldDiv.hide();
        }).keypress(function(e) {
            if (e.which == 32 || (65 <= e.which && e.which <= 65 + 25) 
                                    || (97 <= e.which && e.which <= 97 + 25)) {

                //Create a random RGB value
                var rgb = 'rgb(' + (Math.floor(Math.random() * 256)) + ',' + 
                              (Math.floor(Math.random() * 256)) + ',' + (Math.floor(Math.random() * 256)) + ')';

                //Get the actual value of the key
                var c = String.fromCharCode(e.which);

                //Create a clone of the existing DIV and place the clone next to it.
                newDiv = oldDiv.clone().insertAfter(oldDiv);

                //Provide the new DIV with the Key value and use animate function to apply the bg color(rgb)
                newDiv.html(c)
                        .animate({ backgroundColor: rgb }, 5000)
			            .show();

                //Set the new DIV as the last DIV of the chain.
                oldDiv = newDiv;
            }
        });

That should do it! Here is the complete code…

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>JQ Show Hide</title>
    <style type="text/css">
        .letter
        {
            font-weight: bold;
            color: #fff;
            border: 1px solid #000;
            padding: 5px;
            width: 20px;
            height: 20px;
            left: 0;
            float: left;
        }
    </style>

    <script type="text/javascript" src="http://www.google.com/jsapi"></script>

    <script type="text/javascript">
        google.load("jquery", "1.3.2");
        google.load("jqueryui", "1.5.2");
    </script>

    <script type="text/javascript">
        var newDiv = "";
        var oldDiv = "";
        $(document).ready(function() {
            oldDiv = $("div.letter");
            oldDiv.hide();
        }).keypress(function(e) {
            if (e.which == 32 || (65 <= e.which && e.which <= 65 + 25) || (97 <= e.which && e.which <= 97 + 25)) {
                var rgb = 'rgb(' + (Math.floor(Math.random() * 256)) + ',' + (Math.floor(Math.random() * 256)) + ',' + (Math.floor(Math.random() * 256)) +
')';
                var c = String.fromCharCode(e.which);
                newDiv = oldDiv.clone().insertAfter(oldDiv);

                newDiv.html(document.createTextNode(c))
                        .animate({ backgroundColor: rgb }, 5000)
			            .show();

                oldDiv = newDiv;
            }
        });
        
 
    </script>

</head>
<body>
    <div class="letter" />
</body>
</html>

If you run the code, here is what you will see…

jQuery Animation

Let me know what you think 🙂

links for 2009-12-29

Posted in Daily Links by Sumit Thomas on December 29, 2009

jQuery Show/Hide Content

Posted in jquery by Sumit Thomas on December 28, 2009

[tweetmeme]Here is a technique I normally use to show/hide a content in a div tag. This is quite an useful UI technique in situations where you have to show a Master-Child data, where the child data will be hidden initially and will be shown on demand on click of a image or button.

Lets say I have a web page which will have the following HTML output…

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>JQ Show Hide</title>
</head>
<body>
    <a href="javascript://" title="#content-1" class="toggle">
        <img src="images/plus.png" border="0" />
        Another URL Shortener and it is from Google </a>
    <div id="content-1" class="content">
        Goo.gl is Google’s version of URL Shortening service. Unlike its counterpart tinyurl.com
        or bit.ly, Goo.gl is not a stand alone tool to generate short URLs. For now, the
        only way you can shorten a URL using Goo.gl is by using the Google Toolbar or if
        you have a Feedburner account, integrate your Feedburner feeds with your Twitter
        account.
    </div>
</body>
</html>

Here I have a clickable Title Another URL Shortener and it is from Google and an Image followed by a content inside a div tag. To provide a better user experience we’ll set ourselves the following tasks…

  1. The content inside the DIV tag should be hidden when the page loads
  2. On clicking the Title or the Image, the content should slide down. On clicking again, it should toggle back to hidden state.
  3. The Image should change from plus to minus and vice-versa during the toggle.

Lets create a simple style sheet to perk up the look of the page.

        .toggle
        {
            font-size: large;
        }
        .toggle img
        {
            border-style: none;
        }
        .content
        {
            display: none;
            font-size: small;
        }

After adding a couple of content, our page will look like this…

Master Child Content

Finally, lets write the jQuery code to handle tasks 2 and 3

        $(document).ready(function() {
            $("a.toggle").click(function() {
                var img = $(this).find("img"); //get a handle of the image tag inside title link
                var src = $(img).attr("src"); //get the source of the image 

                //toggle the source of the image to show either plus/minus
                if (src.endsWith("plus.png"))
                    src = src.replace('plus.png', 'minus.png');
                else
                    src = src.replace('minus.png', 'plus.png');

                $(img).attr("src", src);
                
                //get the title of the anchor tag which corresponds to the id of the content div
                var content = $(this).attr("title"); 
                //toggle the display of the content div
                $(content).slideToggle();
            });
        });

        String.prototype.endsWith = function(str) {
            return this.lastIndexOf(str) == this.length - str.length;  
        }

endsWith is a custom javascript function which checks if a string ends with a given substring. This is useful in our case to check if the image source ends with plus.png or minus.png

Putting it all together, our final output will be as follows…

Master Child Content

Let me know if there is a better way of doing this.

Hope you found it useful! Happy jQuerying!

Tagged with: , ,

links for 2009-12-28

Posted in Daily Links by Sumit Thomas on December 28, 2009

links for 2009-12-24

Posted in Daily Links by Sumit Thomas on December 24, 2009

links for 2009-12-23

Posted in Daily Links by Sumit Thomas on December 23, 2009