Twitter Feed Popout byInfofru

OverrideThis.com

Adventures in .NET Software Craftsmanship!

Bundling and Minimizing JavaScript and CSS with ASP.NET 4.5

I am in the process of getting back from the Build 2011 conference in Anaheim, California where  I got to see a ton of stuff related to Windows 8 development and designing Metro style application, and I shall blog a bit on the topic after I have had a good chance to digest all the information.  But right now, I just want to showcase one of the coolest new features of ASP.NET 4.5 “Bundling and Minimization of JavaScript and CSS”.

 

Now for those of you not familiar with the benefits of bundling and minimizing your JavaScript and CSS files, lets just say that reducing the number and raw size of web requests a browser needs to make to interact with your server is going to make your application faster.  A faster web application in most internet business scenarios equals more clients equals more money ( faster = more clients = more money).

 

So you might be asking yourself how complicated is it to setup Bundling and Minimizing of JavaScript and CSS in an ASP.NET 4.5 web application, and the short answer is, not hard at all.  You can setup bundling and minimizing in your Global.asax Application_Start to define what to bundle (See following snippet).

 

protected void Application_Start() {
    AreaRegistration.RegisterAllAreas();
    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);
    RegisterBundlers();
}

private static void RegisterBundlers() {

    BundleTable.Bundles.AddDefaultFileExtensionReplacements();
    BundleTable.Bundles.AddDefaultIgnorePatterns();
    BundleTable.Bundles.AddDefaultFileOrderings();

    var cssBundle = new Bundle("~/Content/css", typeof(CssMinify));
    cssBundle.AddDirectory("~/Content", "*.css", false);
    BundleTable.Bundles.Add(cssBundle);
}

 

Finally, you can modify the reference to your scripts and styles in your layout or master page to target the proper resources.

 

<link href="Styles/css" rel="stylesheet" type="text/css" />
<script src="Scripts/js" type="text/javascript"></script>

 

For more information make sure to read the ASP.NET 4.5 Preview bits release notes (here).

Installing Rails 3.0.7 on Ubuntu 10.10 (Maverick)

Recently I started reading “Learning Rails by Example” by Michael Hartl, and when going through the first chapters I learned the hard way that setting up Ruby and Rails on Ubuntu is not trivial.  So I decided, that for my own sanity, I should document the steps to get the latest version of Rails an Ubuntu environment up and running (Ruby 1.9.2 and Rails 3.0.7 at the time of publishing this blog).  I opted for not using RVM (Ruby Version Manager), which is a decision I expect to regret at some point, but I wanted to keep the process simple and limit the number of tools for an environment that is mainly going to be used for learning purposes.

 

Step 1 – Install Required Software

sudo apt-get install libxslt-dev libxml2-dev ssh
sudo apt-get install curl git-core build-essential 
sudo apt-get install zlib1g-dev libssl-dev libreadline5-dev
sudo apt-get install sqlite3 libsqlite3-dev

Step 2 – Uninstall Ruby and Rails
sudo gem uninstall rails
sudo apt-get purge ruby rubygems

 

Step 3 – Install Ruby 1.9.1 Full

sudo apt-get install ruby1.9.1-full

 

Step 4 – Install Ruby 1.9.2

wget ftp://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.2-p180.tar.gz
tar -xvvf ruby-1.9.2-p180.tar.gz
cd ruby-1.9.2-p180
./configure && make && sudo make install

 

Step 5 – Install Rails

sudo gem update
sudo gem install rails --version 3.0.7
sudo gem install ruby-debug19 ruby-debug-base19 ruby-debug-base19x ruby-debug-ide19 ruby-debug-ide

 

Step 6 – Install SQLite3

sudo gem install sqlite3 sqlite3-ruby

 

References

http://www.web2linux.com/05/installing-rails-3-on-ubuntu-10-04-lucid-lynx/

http://www.rubyinside.com/how-to-install-ruby-1-9-2-and-rails-3-0-on-ubuntu-10-10-4148.html

http://babinho.net/2010/09/installing-rails-3-in-ubuntu-10-04/

http://openrails.blogspot.com/2011/04/install-rails-3-in-ubuntu.html

http://www.ruby-lang.org/en/downloads/

Learning Razor–Writing a Once Extension

So, I have been –officially- using Razor since the ASP.NET MVC 3.0 release and I am loving every minute of it, but from time to time I still find myself looking back at Spark features that I wish I had in Razor. One feature that had been staring at me in the face for a while was the use of the ONCE attribute in spark.  The ONCE attribute allows you to specify with a very elegant syntax that something should just be rendered once no matter how many times is specified. (See code snippet below, or whole documentation here at the Spark website).

 

<!--  add jquery if it hasn't been added yet -->
<script once="jquery-1.5.1" 
  type="text/javascript" 
  src="~/content/js/jquery-1.5.1.js"/>

 

There are probably a couple of ways you could make this work in Razor but the easiest way to go about it is to write a Templated Html Helper (More info on the topic by Phil Haack here, and Andrew Nurse here).  Building a Templated HTML Helper allow us to use a syntax almost as sweet as Spark’s (see snippet below).

 

<!--  add jquery if it hasn't been added yet -->
@Html.Once("jquery-1.5.1",
    @<script src='@Url.Content("~/Scripts/jquery-1.5.1.js")' type="text/javascript"></script>
)

 

While the source code is extremely simple it does rely on the use of the HttpContext to establish uniqueness, this implies that it will safely work across Partial and Child Action calls but will not work across AJAX requests.

 

using System;
using System.Web.Mvc;
using System.Web.WebPages;

public static class HtmlHelperExtensions
{
    private static string RAZOR_ONCE_EXTENSION_KEY_FORMAT 
        = "RAZOR_ONCE_EXTENSION_KEY_{0}";

    public static HelperResult Once(this HtmlHelper helper, 
        string onceKey, 
        Func<object, HelperResult> template)
    {
        var contextKey = string
            .Format(RAZOR_ONCE_EXTENSION_KEY_FORMAT, onceKey);
        return new HelperResult(writer =>
        {
            if (helper.ViewContext.HttpContext.Items[contextKey] == null)
                template(null).WriteTo(writer);
            helper.ViewContext.HttpContext.Items[contextKey] = "OUTPUT_RENDERED";
        });
    }
}

Learning Razor-Shared Content & Layout

As web developer’s in the .NET world we have been spoiled by the advantages of using centralized master pages for managing shared content and layout since the 2.0 version of the .NET Framework.  The ASP.NET MVC 1.0 Framework was no exception we were able to take advantage of our knowledge of ASP.NET master page’s to layout the content of our views.  Now, Razor is no exception either, we still will have the ability to centralize the way content is laid out in our application but some of the mechanics of how the process works have changed.  In fact, one could argue that the way layout is defined in Razor is more inline with the way the Spark view engine (http://www.sparkviewengine.com) does rendering than traditional master pages.

 

Layout Pages

In Razor the concept of a master page is equivalent to a layout page, and one could argue that a similar comparison could be made between the concept of ASP.NET placeholders and sections in Razor.  The following snippet shows what a very basic Razor layout page looks like.  As you can see this is mostly a plain vanilla HTML file the only exception is the directive @RenderBody() which is just a method call that tells Razor where to render the Contents of the child view.

 

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>My WebSite</title>
    </head>
    <body>
        @RenderBody()
    </body>
</html>

 

A basic child view would just specify its layout page and provide the content that is going to be rendered by the @RenderBody() method. As you can see in the following snippet the code for the template is very minimalistic and elegant.

 

@{
    Layout = "~/_SiteLayout.cshtml";
}

<h1>Hello World!</h1>
<h2>Hello World!</h2>
<h3>Hello World!</h3>

 

So far the two samples (snippets) have been very basic, so lets complicate things a bit what if we wanted to have a three column layout.  Well we would still want the main section of the page to drive of the @RenderContent() functionality but for the additional sections you can use Razor’s @RenderSection() method to define additional section’s that can be filled with content from our child views.  The following is the snippet for a three column layout page using CSS.

 

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>My WebSite</title>
        <style>
            #container { width: 700px; }
            #left { float: left; width: 150px; }
            #content { padding: 0 210px 0 160px; }
            #right { float: right; width: 200px; }
            .clear { clear: both; }
        </style>
    </head>
    <body>
        <div id="container">
            <div id="left">
                @RenderSection("left", required:false)
            </div>
            <div id="content">
                @RenderBody()
            </div>
            <div id="right">
                @RenderSection("right", required:false)
            </div>
            <div class="clear"></div>
        </div>
    </body>
</html>

 

The “required:false” parameter specifies if the child view is required to provide content for this section in our case the left and right sections will be optional.   The following is a sample snippet of a page that provides content for all sections, as you can see it is still very minimalistic and elegant.

 

@{
    Layout = "~/_3ColLayout.cshtml";
}

<h1>Main Content</h1>

@section left {
    <h1>Left Content</h1>
}

@section right {
    <h1>Right Content</h1>
}

 

Well, this sums up all the basic information you should need to get started with using layout pages in Razor.  Thanks for reading!

Learning Razor–Writing an Inline Recursive HTML Helper

I have been using Spark (http://www.sparkviewengine.com) as my default view engine for the past 5 or 6 months and I love everything about it.  I like its elegance, simplicity and I depend on some of its features to be efficient in doing most of my daily tasks.   That being said, there is a new kid on the block and his name is Razor.  Razor, will be an out of the box alternative for the ASP.NET WebForm’s view engine for ASP.NET MVC3 (Read Scott Guthrie’s blog on the topic here).   I don’t intend to write a full blown tutorial on Razor,  but as I learn the basics for this alternative view engine, I will try to write some “Learning Razor” posts that relate my experience in learning this new technology.

 

Writing an Inline Recursive Html Helper

The Spark view engine provides you with the ability to define inline macros that allow for recursive calls (Read Louis DeJardin blog on the topic here, and additional documentation here).  These macros are extremely useful for rendering a hierarchical structure such as the one in the following snippet.

 

<ul>
  <li>Fuller, Andrew
    <ul>
      <li>Davolio, Nancy</li>
      <li>Leverling, Janet</li>
      <li>Peacock, Margaret</li>
      <li>Buchanan, Steven
        <ul>
          <li>Suyama, Michael</li>
          <li>King, Robert</li>
          <li>Dodsworth, Anne</li>
        </ul>
      </li>
      <li>Callahan, Laura</li>
    </ul>
  </li>
</ul>

 

Now, the Razor view engine allows you to easily build a hierarchical structure by the use of inline HTML helpers that can be called recursively.  The following is a basic snippet of a “Hello World” inline HTML helper, and a call to trigger its functionality.

 

@HelloWorld("Roberto!")

@helper HelloWorld(string name) {
    <h1>Hello World! @name</h1>
}

 

Finally, if we wanted to output the html from the first snippet using Razor we could write the following inline HTML helper.

 

@model IEnumerable<OrganizationNodeViewModel>
@using MVC3.Playground.ViewModels;
@{
    View.Title = "OrganizationTree";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>OrganizationTree</h2>

@OrgTree(Model, null);

@helper OrgTree(IEnumerable<OrganizationNodeViewModel> nodes, int? parentId) {
    if (nodes.Any(n => n.ParentId == parentId)) { 
    <ul>
        @foreach (var node in nodes.Where(n => n.ParentId == parentId)) {
            <li>
                @node.DisplayName
                @OrgTree(nodes, node.Id)
            </li>
        }
    </ul>
    }
}