Wednesday, January 25, 2012

A Fresh Start to Spine.js for ASP.NET MVC with MeetSpine.js- Part 3

A Fresh Start to Spine.js for ASP.NET MVC with MeetSpine.js- Part 1
A Fresh Start to Spine.js for ASP.NET MVC with MeetSpine.js- Part 2

ASP.MVC Setup

Now that we have the majority of the Spine stuff out of the way, it's time to turn to our ASP.MVC Project. Let's first start by adding a file to our project that will make life quite a bit easier later. Add a new folder to the project at the root level called Helpers. Then add a new class called AssetHelpers to your Helpers folder. We're going to use this class to help offload some of the tedious tasks and hopefully save ourselves some time later. Here is the code that was left out of Kazi's tutorial.


Helpers/AssetHelpers.cs
using System;
using System.Collections.Generic;
using System.Web.Mvc;

namespace MeetSpine.Helpers
{
    public static class AssetHelpers
    {
        private const string Root = "~/assets";

        private static readonly IDictionary<string, string> javaScriptCDNLocations = BuildJavaScriptCDNLocations();
        private static readonly IDictionary<string, string> styleSheetCDNLocations = BuildStyleSheetCDNLocations();

        public static string StyleSheet(this UrlHelper instance, string fileNameWithoutExtension)
        {
            if (instance == null)
            {
                throw new ArgumentNullException("instance");
            }

            bool debug = instance.RequestContext.HttpContext.IsDebuggingEnabled;

            if (!debug && styleSheetCDNLocations.ContainsKey(fileNameWithoutExtension))
            {
                return styleSheetCDNLocations[fileNameWithoutExtension];
            }

            string path = instance.Content(Path(debug, Path("stylesheets"), fileNameWithoutExtension, "css"));

            return path;
        }

        public static string JavaScript(this UrlHelper instance, string fileNameWithoutExtension)
        {
            if (instance == null)
            {
                throw new ArgumentNullException("instance");
            }

            bool debug = instance.RequestContext.HttpContext.IsDebuggingEnabled;

            if (!debug && javaScriptCDNLocations.ContainsKey(fileNameWithoutExtension))
            {
                return javaScriptCDNLocations[fileNameWithoutExtension];
            }

            string path = instance.Content(Path(debug, Path("javascripts"), fileNameWithoutExtension, "js"));

            return path;
        }

        public static string Image(this UrlHelper instance, string fileName)
        {
            if (instance == null)
            {
                throw new ArgumentNullException("instance");
            }

            string path = instance.Content(Path("images") + fileName);

            return path;
        }

        private static string Path(bool debug, string path, string baseName, string fileType)
        {
            return path + baseName + "." + (debug ? fileType : "min." + fileType);
        }

        private static string Path(string relativePath)
        {
            return Root + "/" + relativePath + "/";
        }

        private static IDictionary<string, string> BuildStyleSheetCDNLocations()
        {
            return new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
                       {
                           { "jquery.mobile", "http://code.jquery.com/mobile/1.0b2/jquery.mobile-1.0b1.min.css" }
                       };
        }

        private static IDictionary<string, string> BuildJavaScriptCDNLocations()
        {
            return new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
                       {
                           { "jquery", "http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js" },
                           { "jquery.mobile", "http://code.jquery.com/mobile/1.0b1/jquery.mobile-1.0b2.min.js" },
                           { "jquery.tmpl", "http://ajax.aspnetcdn.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js" },
                       };
        }
    }
}

Next, we need to add a couple of partial views to our Shared folder. Add _Footer, _Header, and _Layout if they aren't already in your project. Here is the code:

Views/Shared/_Footer.cshtml
<footer class="copyright" data-role="footer">
    <p>Copyright © @DateTime.UtcNow.Year.ToString("0000") <a href="javascript:;">Yo Yo Inc</a></p>
</footer>

Views/Shared/_Header.cshtml
@model string
<header data-role="header">
    <h1>@(string.IsNullOrWhiteSpace(Model) ? "Meet Spine" : Model)</h1>
</header>

Views/Shared/_Layout.cshtml
@using MeetSpine.Helpers
<!DOCTYPE html>

<html>
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <link href='@Url.StyleSheet("jquery.mobile")' rel="stylesheet" />
        <script src='@Url.JavaScript("lib/jquery")'></script>
        <script src='@Url.JavaScript("lib/jquery.mobile")'></script>
        <title>Meet Spine</title>
    </head>
    <body>
        @RenderBody()
        <script src='@Url.JavaScript("lib/spine")'></script>
        @RenderSection("bottomScripts", false)
    </body>
</html>

Update the Error page to the following:
Views/Shared/Error.cshtml
<div id="error-page" data-role="page">
    @Html.Partial("_Header", "Error")
    <div data-role="content">
        <p>Sorry, an error occurred while processing your request.</p>
    </div>
    @Html.Partial("_Footer")
</div>

Under Views, add a new folder called Dashboard and add the partial pages _ActivitySheet and _TaskEditor, and view page Index from Kazi's tutorial. You'll have to add an extra line of code to your Index view to get it to work if you're properly namespacing your project. Here is what the final version should be.

Views/Dashboard/Index.cshtml
@using MeetSpine.Helpers
<div id="main">
    @Html.Partial("_ActivitySheet")
    @Html.Partial("_TaskEditor")
</div>
@section bottomScripts {
    <script src='@Url.JavaScript("lib/jquery.tmpl")'></script>
    <script src='@Url.JavaScript("lib/date")'></script>
    <script src='@Url.JavaScript("models/task")'></script>
    <script src='@Url.JavaScript("controllers/activitysheet")'></script>
    <script src='@Url.JavaScript("controllers/newtask")'></script>
    <script src='@Url.JavaScript("dashboard")'></script>
}

You're project should run at this point, but you're going to notice that the styling is all messed up because we haven't added it yet. You'll need to copy the stylesheets and images folder out of Kazi's project, hopefully you've downloaded that it by now, and put them in assets folder in your own project. (Note: unless you update the routing, you'll have to go to http://localhost:port/Dashboard to see what we've done)

At this point, you should be good to continue with Kazi's tutorial on Spine.js and ASP.MVC keeping in mind that he forgets to tell you where to place your code files.


I hope this helps to clarify some of Kazi's otherwise wonderful tutorial for those of you out there who might just be starting with ASP.MVC and Spine.js

No comments:

Post a Comment