Using MonoRail ViewComponents with the Spark view engine

Although I was able to find some documentation and samples (mostly through the unit tests) of how to use a ViewComponent with the Spark view engine, details were sketchy, so I’ll share some quick tips to those who are scratching their heads as I was.

Using a block ViewComponent

Support for block view components is pretty evident in Spark, as shown in the following example, which illustrates the use of the AuthenticatedContent view component.

<authenticatedcontent>
	<logged>
		This content is shown when the user is logged in.
	</logged>
	<notlogged>
		This content is shown when the user is NOT logged in.
	</notlogged>
</authenticatedcontent>

Using the CaptureFor ViewComponent

The CaptureFor component is one useful way to allow a sub-view to “inject” data into a layout. I use this all the time to allow a rescue page to change the page title when an error occurs.

On your layout page, you inject the page title as you normally would (so a controller can inject it via the property bag).

<title>ComputerSims Baseball: $!{ViewData["PageTitle"]}</title>

In the view, the CaptureFor component is called as an HTML tag.

<capturefor id="pageTitle">An unexpected error has occurred</capturefor>

Calling a ViewComponent with view and static data

This is one that perplexed me. I have a custom menu component (called MenuComponent) which accepts a name parameter. I tried calling it like this:

<menu name="mainmenu" />

Unfortunately, that threw an error: “The name ‘mainmenu’ does not exist in the current context“. Fortunately, Spark exceptions are easy to read (you can see the C# code it generates and thus find the error). Apparently, in the above example, “mainmenu” was expected to be a variable in the view page and was not being treated as static text. To use static text, you put single quotes inside the double quotes.

<menu name="'mainmenu" />

Problem solved. I can’t say it’s the preferred way based on my experience thus far (I’d prefer requiring ${mainmenu} for variable injection), but since I’m new to this, I won’t criticize much.

Simple layouts and views with Spark and MonoRail

Yesterday, I wrote about the coolness of The Spark view engine (and a brief history of web programming). As I explore more, I’ll share my experiences here in hope that it shortens other people’s learning curve.

Today’s topic is the basics: writing a simple layout.

Spark offers full support for layouts and views. As with any other view engine, the file extension (by default, .spark) of both your layout and view files must match.

A simple layout looks like this:

<html>
<head>
<title>A simple layout</title>
</head>
<body>
<h1>A simple layout</h1>
<use content="view" />
</body>
</html>

The only thing that isn’t HTML is the <use content="view" /> tag. This tag denotes where in the layout (master template) to embed the content from your view. In NVelocity, we used ${ChildContent} declaration in NVelocity, or the ${ChildOutput} declaration in Brail. Yes, it’s that simple.

Often times, we want to inject some view data into our layout, such as the page title. Let’s say our controller was sending a PageTitle to the view:

public void Simple()
{
PropertyBag["PageTitle"] = "Still a simple sample";
}

How would we get this injected into the title tag in our layout? The quick way is to reference your viewdata, as shown below.

<head>
<title>$!{PropertyBag["PageTitle"]}</title>
</head>

The syntax is similar to that of NVelocity (even the use of the exclamation point to suppress the rendering of nulls), but we’ve got to explicitly reference the PropertyBag. Interestingly, you can also write $!{ViewData["PageTitle"]} — to Spark, both PropertyBag and ViewData are the same. There are two disadvantages with this method:

  1. It’s not as clean as $!{PageTitle}, which we can do in NVelocity.
  2. The result is not strongly-typed, which limits your ability to work easily with complex types.

The solution to these two problems is to specify a Spark viewdata tag and declare the name and type of the view data objects you want to expose. Note the changes in the code below.

<viewdata PageTitle="string" />
<html>
<head>
<title>$!{PageTitle}</title>
</head>

Much cleaner! The Spark web site has an example which shows the use of a strongly-typed collection that illustrates this further.

That’s it for now. It’s just a quick start, but there’s a lot more to Spark, and I highly recommend it to MonoRail users.

The Spark View Engine (and a brief history of web programming)

spark I should have gone to bed early last night (after all, I did wake up at 4:30AM yesterday morning). Unfortunately, a spark of inspiration quite literally kept me up later than normal sleep cycles dictate… but what a spark it was.

To understand the spark, you have to understand my history of server-side web programming.

In the beginning

My first experience with server-side web programming was with Allaire ColdFusion some ten years ago. What was great about ColdFusion is its use of a tag-based scripting language, CFML, as illustrated below.

<cfset value = "Hello" />
<cfoutput>
   #value# Bob!
</cfoutput>

After ColdFusion, I came across what is now known as “Classic ASP” – and my web code looked less and less like HTML.

<% value = "Hello" %>
<%= value %> Bob!

Classic ASP felt more like programming, less like web programming. Quite accurately, it was web programming via scripting. I missed the tag-based syntax of ColdFusion.

Then there was ASP.Net, which at first glance looked like it was a return to tag-based web programming! Well, almost… along came this weird codebehind model, and the entire stateless request/response nature of the web was bastardized.

<asp:label runat="server" id="greeting" /> Bob!
// and in the codebehind
greeting.Text = "Hello";

And so there I was until I found Castle Monorail, which returned web programming to its core, thanks to a fantastic MVC architecture. With MonoRail, you injected text into your web pages using a template engine. For me (and most other newcomers to MonoRail), that meant NVelocity.

${value} Bob!
// and in the controller
PropertyBag["value"] = "Hello";

Now assignments happened somewhere detached from the view (i.e. the controller), and my web page was looking rather clean. I still yearned for the tag-style days of ColdFusion.

Enter Spark, a tag-based view engine for MVC platforms (i.e. MonoRail!). Spark gives you almost all the power of C# and the .Net Framework within your view, but does it using a syntax that is entirely tag-based, as shown in the following example from the Spark web site.

<var names="new [] {'alpha', 'beta', 'gamma'}"/>
<for each="var name in names">
  <test if="name == 'beta'">
    <p>beta is my favorite.</p>
    <else/>
    <p>${name} is okay too I suppose.
  </test>
</for>

With this, the presentation logic in your view looks like HTML. It makes the resulting view file much more semantic otherwise.

The Spark view engine is an impressive effort by Louis DeJardin, who deserves kudos for his efforts. Not only does the code work great, he’s got plenty of documentation on how to get it working with Castle MonoRail – even plenty of references to Windsor integration.

I’m switching a major project from NVelocity to Spark, and plan to blog more about this in the future. In the meantime, check out Spark – there’s lots to read and learn, and the examples available in the Subversion repository are fantastic.

Google AdSense ViewComponent for MonoRail

Like many, I use Google AdSense to host ads on my web sites. Including the ad code typically requires you to paste a block a block of JavaScript onto the page. I don’t mind injecting the JavaScript, but I wanted to come up with a better way.

The solution I came up with was a quick MonoRail ViewComponent, AdUnit. It has a simple purpose: to render a block of code for an ad unit of a given size.

The first task was to create an enum which represented all the possible ad unit sizes, based on what’s offered by Google. Continue reading