Saturday, 20 February 2010

Partials in Spark View Engine

Continuing my journey with Spark, the next natural stop for me after the basics was “partials”. I am a uber-fan of DRY (almost fanatical) so was keen to try and cut down the dupe of HTML etc. I thought I would share the “partials basics” for both you and me :)

What Are “Partials”?

“Partials” are basically snippets of HTML/”code” markup that can be used throughout your MVC application. This reduces code duplication and helps keep your site maintainable. It can also make your markup easier on the eyes, since you can isolate chunks of markup into “units of functionality” (e.g. a “navigation bar”).

What Are Partials NOT?

UserControls. People often relate/confuse partials with user controls, and they are NOT. While UserControls can encapsulate HTML, code behind, events and be packaged into assemblies etc. Partials are still (or at least should) be pretty “dumb” views.

Why Use Partials (and MVC) When UserControls Do More?

If you are more interested in mashing up code with markup etc, then MVC is probably not for you. MVC is about clean separation of concerns and good design. Partials don’t have code because Views shouldn’t have code (other than the absolute minimum, e.g. for-each).

How Do I Use Partials in Spark?

Naming Conventions

Another reason I like Spark is because it reinforces the idea of “convention over configuration”. We shouldn’t need things like XML and additional markup if we establish a standard and stick to it.

In short, put Partials in your “Views\Shared” folder and prefix them with an underscore (e.g. “_MyPartial.spark”). This identifies to Spark that the markup is actually a partial.

Not-Recommended Syntax (RenderPartial)

Pretty explicit syntax, but not recommended:

   1: <render partial="_MyPartial" />

Preferred Syntax

This is the recommended way to use a partial:

   1: <MyPartial />

Note here that we just use the partial name (without the underscore prefix) and it all “just works”.

Injecting Variables in to Partials

So, we have referenced our partial – how to we get data in to them?

   1: <partialName variableName="value" />

And the partial markup (to use the variable):

   1: <p>
   2:   String Variable: ${myString} <br />
   3:   Integer Variable: ${myInt}
   4: </p>

Note here we are not explicitly setting types – it all kind of “just works” for 99% of the times. Just be careful with any specific formatting requirements (this should in theory be handled by your model).

Model Data

It is actually recommended that you actually get required model data in the parent view, not the partial and then pass that value to the partial. This ensures that the partial fails if you do not pass in from the top. This is very similar to “dependency injection” as well as remove “smarts” from the partial.

In the view that uses the partial:

   1: <viewdata model="SomeType" />
   2: <MyPartial user="Model" />

See? We are passing in the “model” data as a variable – meaning the partial is less tightly bound to the implementation.

We can then access the model data in the partial by using the variable like so:

   1: <h2>${user.Name}</h2>
   2: <ul>
   3:     <li>T: ${user.Phone}</li>
   4:     <li>E: ${user.Email}</li>
   5: </ul>

The partial is focused on rendering the view data passed to it (a “user”) as opposed to retrieve it from ViewData/Model.

Complex Objects

Used in exactly the same way as above – just pass the object as a variable to the partial.

The key thing to note here is that the view take no requirements on the view (i.e. we don’t need to “type” them) we just use the “dollar syntax” to access a property and assume it is there. If anything is amiss, things will blow up. This sounds bad, but the truth is this – your views should be so dumb they literally do nothing.

For example, some people ask “what if the object is null?” – well, I would ask “What if the object is null? What does that mean in terms of business rules? Why isn’t that reflected in the ViewModel that is returned from the service/model layer? Record not found you say? Why didn’t you (or your model) tell me that?”.

In Summary

  • Views should be simple/stupid, Spark directly supports/reinforces that.
  • I (personally) find the Spark syntax very clean and intuitive.
  • If you are wanting your views to be “smarter” – you are doing something wrong.

Tuesday, 9 February 2010

RCP: Spark View Engine Bootstrapper

So, tonight I had a RCP session with @JohnnoNolan – we decided that for our topic, we would like to “File > New Project” and see what it is like to replace the default ViewEngine in ASP.NET MVC with the Spark View Engine.

Why Spark View Engine?

I have heard a lot of buzz about it from the developer community. Also, I heard the podcast on Hanselminutes and the notion of it all just sat right with me - there shouldn’t be such an epic battle between HTML/C# in your views. Our sole purpose in the View is to render HTML based on some model data – make it easy.

RCP Session Aims

Neither myself or Johnno had any real experience with Spark before the session. As a starting point, I thought it would be good to cover what I would consider to be the “basics” for views:

  • Using variables from ViewData.
  • Using strongly-typed model data.
  • Using master pages.

I decided to spend 1 hour before the session having a quick run-through of the install process and the basics in the hope of making the session more productive. This definitely helped (and I would always recommend spiking on something anyway).

Session Outcomes

I just want to (briefly) touch on what we got out of the session.

Install is EASY
  • Go to the Spark download page.
  • Get the latest stable release.
  • Extract the files in the zip to wherever you store your third party assemblies.
  • Create a new MVC application (Note there is a “gotcha” here with MVC versions – see below).
  • Add a reference to Spark and Spark.Web.MVC.
  • Add the following to Global.cs MvcApplication::Application_Start:
   1:  protected void Application_Start()
   2:  {
   3:    ViewEngines.Engines.Add(
   4:        new SparkViewFactory());

That’s it – note there are some additional configuration steps that you may need, but I didn’t.

I definitely recommend also installing the VS Integration bits that come with the release package – makes working with Spark a LOT easier (including adding much-needed stuff like code colorisation).

ASP.NET MVC 1 & 2 Gotcha

Even though MS have mentioned in MCP programs, podcasts and MSDN documentation about NOT changing public API’s – guess what they did in MVC2? :) It turns out, there was a change to a constructor for a key class. This means that: If you do not have MVC 1 installed, then you MUST install it to use Spark (at this time).

NOTE: You can use Spark in MVC2 applications, you just need the MVC1 framework available.

I think this essentially boils down to Spark having a reference to System.Web.MVC, but “Specific Version” is set to “false” (so it auto-upgrades reference to 2.0 if 1.0 isn’t available). This is causing it to go BOOM!* With this error:

Method not found: 'Void System.Web.Mvc.ViewContext..ctor(
  System.Web.Mvc.ControllerContext,
  System.Web.Mvc.IView,
  System.Web.Mvc.ViewDataDictionary,
  System.Web.Mvc.TempDataDictionary)'.

* If anyone thinks I have misinterpreted the problem here – do comment and I will update!

Lesson to be learned? If you are building code against assemblies produced by a third party – set “Specific Version” to true to ensure that if they update it, your application doesn’t break :)

ViewData is Case Insensitive, “model” is NOT.

These are all the same, since the keys for ViewData are case-insensitive:

   1:  <viewdata Message="string" />
   2:  <viewdata MESSAGE="string" />
   3:  <viewdata MesSaGE="string" />

Obviously, the C# code will need to match the case used in declaration – for example:

   1:  ${Message}
   2:  ${MESSAGE}
   3:  ${MesSaGE}

However, the code required to setup Model data appears to be case sensitive (in kind of a weird way IMO).

   1:  <!-- Note the 'model' Attribute is All Lowercase -->
   2:  <viewdata model="ModelType" />

To access in C#:

   1:  // Note 'Model' has Capital 'M'
   2:  ${Model.Property}

That one caught me out for 5 mins.

Master (Layout) Pages

Unfortunately, we never got around to setting up the master pages because we lost a fair bit of time to the MVC 1 vs 2 issue above.

However, the documentation for Spark is fantastic, and adding layout pages looks just as easy as the rest of Spark. So not really “worried” about doing this.

I <3 Spark

I really, really enjoyed learning about Spark – just reading the documentation, I couldn’t stop grinning. The syntax/markup choices just makes sense (on the whole).

Looking at the markup, I have the distinct feeling that it is all easier for designers etc. to stomach – so if you are outsourcing design, I think Spark may well be a great way to go.

And for one line of code in Global (two if you want to completely remove WebForms)? Why didn’t I do this sooner?

Definitely going to be making sure Spark is the first thing I setup after “File > New Project” in future.

Props to Louis DeJardin (@loudej) on doing such a great job!

Sunday, 7 February 2010

TomatoTimer Now on GitHub

Not sure if you guys remember me talking about TomatoTimer in the past, but after some thought I have decided to whack it on GitHub as a public repository.

Why GitHub?

Cos it’s awesome. Even when it fails it’s awesome because I think Octocat is awesome :)

Why a Public Repo?

Put simply, there are people that were interested in using the application, and there a couple of bugs in it that I can’t guarantee a fix time on. I am not (and likely to remain not) invested in WPF applications at all at this time. I am instead focusing my efforts on ASP.NET MVC. So, rather than keep people waiting, I thought I would throw the code online so they can at least use it.

If it just so happens that someone sees the problem and they send me a pull request, even better.

Where Do I Get the Code?

You can get (read-only) access to the repository here: http://github.com/robcthegeek/TomatoTimer. The code is C# 3.5, with a WPF front-end. xUnit is used for testing, and Rhino Mocks for mocking (although likely to remove as I have been working on a “mocks ban” recently and actually found it quite nice :).

Everything you need should be in there, if you come across any problems, please raise an issue and I will get it sorted ASAP for you.

Anything Else I Should Know?

The code was written a long time ago, also there was a fair bit of “let’s try this” – so the quality is not 100%. But if/when I get the chance I will do my best to clean up :) (more motivated to do so now it is in the public eye!) ;)

Hope you find it useful!

Tuesday, 2 February 2010

“Getting Started with Ruby” Kata

I have been having talks/ideas for some time about starting a bit of a affair with Ruby. As a .NET geek, you may be wondering “why?”.

I don’t want to “go on” too much here, if you’re curious about these, please feel free to ask:

    • It’s Designed for Programmers
    • It’s Dynamic and Not JavaScript
    • Rails Looks Interesting
    • Massive Community Movement/Involvement
    • Strong Open Source Community

I got thinking. I want to get started, but have no idea where to begin. I make no claims that I am anything other than a complete n00b.

So, I started feeling my way through the darkness and decided to try and formalise it into a kata that can be repeated.

NOTE: This is totally a “bootstrapping” kata – if you have done anything beyond the basics with Ruby, this is of no good to you!

The Kata

Problem

Create a simple class that returns a number formatted as a percentage. For whole numbers, “zero” decimal places should be removed, for fractions, they should be formatted to two decimal places.

For example:

  • “10” => “10%”
  • “10.2” => “10.20%”
  • “10.268” => “10.27%”
  • “10.00” => “10%”

When the input is less than zero or greater than 100, then the result should be capped at zero or 100.

For example:

  • “200” => “100%”
  • “-54” => “0%”
Steps

These are the rough steps I followed:

  • Install your IDE of choice (I opted for Netbeans because it is free and looked reasonable – please comment if you know better IDEs!).
  • Create your first (failing) test (I did “0” => “0%”).
  • Create a class to pass the test.
  • Add tests for more whole numbers.
  • Add tests for the range cap.
  • Add tests for two decimal place formatting.
  • Add tests for input (e.g. non-numerical strings).

I decided to stop there.

My Thoughts/Points to Note
  • The default unit test framework baked in to Ruby requires that test method names start with “test”.
  • I love the fact that unit testing is baked into the framework, and IDE’s (cleanly) support it out-of-the-box.
  • I spent AGES (like an hour) wrestling with the formatting to two decimal places. I couldn’t find any decent rounding function in the framework. My implementation is probably lame, feel free to send a pull request :P
  • I am still really getting used to the “type-less” nature of parameters etc. so not sure if I should be doing more (or even less) work with validating inputs etc. (i.e. put all our faith in duck typing, or program defensively).

You can check out my code here.
NOTE: I think this link may go down when I merge in the changes – if so, just ping me and I will update.

So, a real learning journey. Felt weird (and admittedly scary) to be sat there looking at code I didn’t really understand again. Definitely a good thing for my geek-head :)

Yes, this kata took me way longer than I had hoped/expected (*cough* ~2.5 hours).

What are your thoughts on this kata? Too little? Too much?