Blog Archives

A few thoughts on jQuery templating with jQuery.tmpl

I spent some quality time with Dave Reed’s latest revision of John Resig’s jQuery.tmpl plugin recently, migrating a small project from jTemplates. Since both the jQuery team and Microsoft team have requested feedback on jQuery.tmpl, I decided to write about my experience using it (as I am wont to do with these templating proposals).

Overall, jQuery.tmpl is a great step in the right direction. It’s small, it’s simple, and it’s fast. Overloading append() to allow the append(Template, Data) syntax is phenomenal. That approach feels more like idiomatic jQuery than anything else I’ve used, including jTemplates.

However, if this template rendering engine is going to succeed broadly, I feel there’s one important feature still missing. Additionally, there are a couple ancillary features that are present in the current proposal, but should be protected.

Composition

One area where jTemplates still comes out on top is template composition – also known as nested templates. Specifically, this refers to the ability for templates to contain references to other templates, and the ability to render that entire group as a whole.

The need for template composition may be hard to see in simple examples, but most non-trivial scenarios benefit from template composition. Dave mentioned the example of having a person template that embeds a separate template for displaying information on one or more phone entries about those person records.

That’s a good example, but take it one more step to understand where composition really shines. Consider the possibility that each of those phone records has a type (e.g. Mobile, Home, or Work) and that each type must be presented with different markup.

Template composition provides a clean solution to this problem. By creating separate templates for each type and then rendering the correct amalgamation of those templates, the template code remains simple (but is powerful).

A composition workaround in jQuery.tmpl

Currently, something resembling nested item templates are technically possible via the each keyword in jQuery.tmpl, but it’s not pretty. This example from the jQuery.tmpl demo illustrates that approach:

// Data
cities: [ "Boston, MA",
          "San Francisco, CA" ]
 
// Template
Cities: {{each(i,city) cities}}${city}{{/each}}

Even for this most simple case, the syntax is rough. Not the sort of readable simplicity that we’ve come to expect from jQuery.

More importantly, extending that to conditionally render different fragments of markup would be much more difficult.

A cleaner workaround (but it’s a trap!)

The jQuery.tmpl demo also contains this seemingly elegant alternative:

// Data
cityJoin: function() {
  return this.cities.join(", ");
},
cities: [
  "Boston, MA",
  "San Francisco, CA"
]

By embedding a function in the data, referencing that object key in a template returns the result of the cityJoin function. Thus, jQuery.tmpl renders the function’s result, not the function declaration’s actual text.

That technique dramatically simplifies the template itself:

// Template
Cities: ${cityJoin}

While that approach does succeed in avoiding the messy template code that each requires, it tightly couples concerns which should not be.

When this is put into practical use, the data object will usually be requested from the server-side. Would my business logic or data repository tier need to inject the joining function? I don’t think I could bring myself to do that.

Further, it doesn’t really address the real-world scenarios I’ve encountered. A callback function to format data won’t feasibly scale to rendering heterogeneous chunks of markup. Effectively, it’s the same as the each solution, with the pain point shuffled around a bit.

How I think it should work

As long as there’s some way to name and render sub-templates, I don’t care how exactly it works.

I wasn’t crazy about jTemplates’ {#include} syntax at first, but it’s okay once you get used to it. Most any syntax shouldn’t be difficult to learn and acclimate to.

Since jQuery.tmpl already provides for caching the templates in jQuery.templates, all that’s really necessary is a method for rendering those named templates within other templates.

A concrete example

This example simplified a bit, but is functionally similar to client work I come across regularly. To be clear, this is something I’m currently using today, not something I’m just theorizing as a good idea.

I want to be able to take data that isn’t necessarily homogeneously structured:

{InvoiceItems: [
  { ItemType: 'Product',
    PartNumber: '99-Designs-Logo',
    Description: '99 Designs Logo design',
    TotalCost: 450 },
  { ItemType: 'Service',
    DescriptionOfWork: "Website development",
    TotalCost: 5000 },
  { ItemType: 'Service',
    DescriptionOfWork: "Deployment and testing",
    TotalCost: 300 }
])

And use a set of templates like this to render that data (did I get the each syntax right in #Invoice?):

{#ServiceItem}
<tr>
  <td colspan="2">{$DescriptionOfWork}</td>
  <td>{$TotalCost}</td>
</tr>
 
{#ProductItem}
<tr>
  <td>{$PartNumber}</td>
  <td>{$Description}</td>
  <td>{$TotalCost}</td>
</tr>
 
{#Invoice}
<table>
  <-- Fancy thead here -->
  {{each(i, InvoiceItem) InvoiceItems}}
    {{if $InvoiceItem.ItemType === 'Service'}}
      {{render('ServiceItem', InvoiceItem)}}
    {{else}}
      {{render('ProductItem', InvoiceItem)}}
    {{/if}}
  {{/each}}
</table>

Scenarios just like that one are common in my current work with jTemplates. Imagine trying to implement that with each or an embedded callback function.

Now imagine you wanted to conditionally render those same row templates as sub-items in more than one master template (e.g. maybe there’s also a credit memo template similar to the invoice, but not identical). The burden of maintaining an application like that quickly compounds without template composition.

Again, the exact syntax doesn’t matter. Any implementation that provides the functionality would be a win.

External templates

I’ve never understood the desire to cruft up a page with inline templates. Whether they’re hidden through CSS or embedded within a text/html type script element, cluttering my markup with templates feels sloppy.

jTemplates introduced me to the idea of storing templates externally, and then asynchronously loading them only as necessary (example). I adopted that approach at nearly the same time I began using jTemplates and haven’t looked back since.

My affinity for remotely template loading caused me to lobby for remote templates both in the DataView and more recently in jQuery.tmpl. However, what I hadn’t considered is that it’s already easy to load external templates with jQuery’s built in AJAX functionality. With the template loaded into a string variable, the append(TemplateString, Data) syntax connects the dots perfectly.

All of that is simply to say: Please do leave the append(TemplateString, Data) syntax intact. As long as we can provide templates via string variable, built in remote template loading isn’t necessary.

On the need for in-template logic

I’ve heard some dissention on the issue of conditional logic within templates.

Philosophically, I agree; mingling logic into your presentation/view is dangerous. It’s always a slippery slope, at best. However, the pragmatist in me ultimately cannot agree with the hard-line approach of banishing it completely.

A screenshot of conditionally rendering invoice display names depending on their invoice numberA project I’m working on is a good example. My client-side code must display a collection of invoices sourced from a legacy backend, each with an upgrade number. Upgrade 0 must be displayed as “Original Invoice”, but the rest should be displayed as “Upgrade n”.

A conditional in the template makes quick work of the problem (this is jTemplates syntax, not jQuery.tmpl):

{#if $T.Upgrade == 0}
  Original Invoice
{#else}
  Upgrade #{$T.Upgrade}
{#/if}

Since it’s purely presentational logic, it belongs in the template as much as it does anywhere. Please do keep that functionality available, even if it does have potential for abuse.

In addition to the currently available conditional keywords if and else, elseif and switch would both be nice additions.

Conclusion

Overall, I’m excited about the potential of seeing jQuery.tmpl integrated into jQuery core, or even made available as an “official” plugin. As much as I like jTemplates, support and documentation for it is spotty at best.

Ultimately, we will all benefit from standardizing on an official templating solution rolled into the jQuery core, rather than each of us using our obscure favorite.

I’m curious what you think. Am I the only one using template composition? Anyone want to make a convincing case against conditional logic in templates?

###

Originally posted at Encosia. If you’re reading this elsewhere, come on over and see the original.

A few thoughts on jQuery templating with jQuery.tmpl

Matching Color the Easy Way

In my opinion, color matching is something of an art form. There are so many different ways to arrive at a final color and look that it can drive you nuts! Lets see, there are alcohol and water soluble dyes in liquid and powder form, oil stains, water-based stains, pigments, toners, gel stains, glazes, and the list goes on and on. But does it always have to be this convoluted?? Let me spoil the ending for you: NO!

I was fortunate to work in a refinishing shop for a while and I had the opportunity to learn about color matching using various techniques and materials. We used to mix all kind of crazy stuff together to get that perfect match. Over the years, I began to realize that many times the perfect match is sitting in a can on the shelf. And if you can find the perfect color in a commercial product, I say “why not?”. The formula should always (hopefully) be consistent and if you ever need to reproduce the color again in the future, you’ll thank yourself.

This weekend, my buddy Ron from RJones Woodworks stopped by to bring me Dunkin’ Donuts coffee. Well, to tell you the truth, that’s my standard color matching consultation fee. Pretty reasonable, right? Well anyway, he’s building a custom piece for a client who wants the color to match a particular bamboo cutting board. Now lets get one thing straight: there isn’t a damn thing you can do to oak to make it look like bamboo. This is an important detail that many clients don’t realize. I have had more than one customer ask me to refinish something made from pine so that it looks like something else made from oak. I would match the color perfectly, only to find the customer disappointed on delivery day because the pieces don’t look the same. So if you are ever doing a match for a client, its incredibly important to manage their expectations. OK enough business advice.

01So we were all prepared to pull out the pigments, dyes, lacquer and the HVLP. But before diving into that craziness, we decided to take some dyes and stains from the cabinet and see if we couldn’t find a pre-made solution. We tested numerous water and oil based stains and dyes (all General Finishes). From left to right we have oil-based Pecan, oil-based Antique Cherry, American Cherry gel stain, Nutmeg gel stain, Light Brown water-based dye stain, and Pecan water-based wood stain. The differences were subtle: some had more red, some had more brown, others had more yellow. But all of them were, of course, affected by the red oak laying underneath the color. This is why its always important to test your stains on an actual scrap piece of the material you plan to work with.

05Now the bamboo itself contains a range of colors from light to medium to dark brown, and mimicking the exact look would be nearly impossible. But if we could find a color that was a happy medium between the light and dark streaks, we would be in business. When it was all said and done, we decided on the Light Brown dye stain. We stained a larger area to confirm the match and I think we made the right choice. Honestly, I don’t think we could get any closer even if we tried. 04So once Ron gets the client’s approval, this is a done deal. Instead of spending hours trying to experiment with color, Ron can now hop online and order up a can of Light Brown Dye Stain. And if his client ever commissions another piece in the future, its going to be incredibly easy for him to match the color.

All in all it was a fun morning. And if anyone else wants to bring me free Dunkin’ Donuts coffee, I’ll be more than happy to help you do some color matching.


Is Silverlight the new WebForms?

WebForms to Silverlight - Just when I thought I was out... they pull me back in!

While there’s no question that HTML, CSS, and JavaScript form the foundation of modern web development, achieving fluency hasn’t been easy for everyone. In particular, the transition from stateful development with pixel-precise layout – such as VB6 offered – has proven to be especially difficult. HTTP’s stateless nature and HTML’s relatively imprecise layout present a new, different set of challenges.

WebForms aspired to insulate us from those inconveniences. Promising rapid, drag ‘n drop layout and event-driven programming, WebForms was an attractive choice for anyone struggling with web development closer to the metal. Unfortunately, it has become apparent over the years that the WebForms abstraction, while convenient, can easily cause more problems than it solves.

More recently, Silverlight’s WYSIWYG layout and choice of familiar CLR languages have made it a similarly enticing alternative to HTML, CSS, and JavaScript among some .NET developers, but is history repeating itself? Are we leveraging Silverlight to move the platform forward or is it being used as another crutch?

Specifically, I want you to consider three areas that are negatively impacted by overzealous use of Silverlight: Usability, accessibility, and maintainability.

Usability

The Microsoft Thrive for Developers site (which has some great content) is what originally motivated this post. I’ve been percolating these concerns for some time, but my initial experience there served as a lightening rod for them.

After landing on the page, I was greeted by this progress indicator and watched it load for several seconds:

The loading indicator on an MS Thrive horizontal accordion

Expecting something worthy of using Silverlight, I was content to wait on the Silverlight to load. Unfortunately, the entire thing turned out to be nothing more than a simple horizontal accordion:

The horizontal accordion after it finished loading

Even forgiving the excessive load time, these Flash/Silverlight-based horizontal accordions are a plague on usability. If you put something in my browser that looks like links and images, it should behave like links and images!

A partial list of the various usability problems that arise include:

Context Menus – When I right click a button intent on opening a link in a new tab or window, seeing a context menu with a single “Silverlight” option is not a good experience. Eliminating the standard context menu defeats several features that you may not use, but some of your users do.

Similarly, when your site thwarts the gesture plugin I use, you’re only hurting yourself. When I can’t drag a site’s links into background tabs without interrupting what I’m doing, I’m far less likely to view as many pages as I normally would.

Browser HistoryJust as with WebForms before, fully Silverlight based sites break the browser’s expected history, navigation, and bookmarking features by default. There are workarounds, but it’s uncommon to see them actually used.

Text Field Interop – Because Silverlight TextBox controls are not HTML input elements, they sacrifice a wide range of functionality, from password managers to the ability to drag ‘n drop selected text to and from these fields.

Using these islands of Silverlight reminds me of the usability of WebForms Buttons and LinkButtons used for navigation, which have the same problems. It wasn’t a good idea to break the browser’s basic functionality then and it still isn’t now.

Accessibility

It’s no secret that plugin-based technologies like Silverlight obscure their content in an inaccessible manner. Tempting as it sometimes is to turn a blind eye to this problem, accessibility is something that everyone should care about.

Though Microsoft is taking great steps to mitigate Silverlight’s accessibility issues, by embracing the W3C’s ARIA initiative, ARIA is no panacea. It is a compromise to improve the situation, but not a solution to the fundamental problem. In fact, the W3C’s first recommendation when building an ARIA compliant application is:

Use native markup when possible.

 

Use the semantic elements that are defined in the host markup language. For example, with HTML or XHTML, it is better to use the native checkbox than to use a div element with role checkbox as these should already be accessible through your browser.

Even if every one of your site’s users are without physical impairment, accessibly designed sites yield a variety of other benefits as byproducts. For example, what do you think a search engine spider will glean from this markup?

<object data="data:application/x-silverlight-2," 
        type="application/x-silverlight-2" 
        style="width: 775px; height: 273px;">
    <param name="source" value="xap/ThriveSilverlight.xap"/>
    <param name="background" value="transparent" />
    <param name="windowless" value="true" />
    <param name="minRuntimeVersion" value="2.0.31005.0" />
    <param name="autoUpgrade" value="true" />
</object>

Probably not much. At least it might rank well for application/x-silverlight-2.

Now, compare that to the semantic HTML markup that might be used to implement the same functionality with a bit of CSS and JavaScript:

<ul>
  <li id="Advance">
    <h2>Advance Your Career</h2>
 
    <p>Take control of your career path. We've got industry
    experts and developer community leaders to give you a hand.</p>
 
    <a href="Advance/CareerResources">
      <img src="GetCareerResources.png"
           alt="Get Career Resources" />
    </a>
 
    <a href="Advance/TrainingCert">
      <img src="GetTrainingResources.png"
           alt="Get Training Resources" />
    </a>
  </li>
  <li id="Enhance">
    <!-- More content here -->
  </li>
  <li id="Connect">
    <!-- And again -->
  </li>
</ul>

The difference speaks for itself.

In the same vein, an application that exposes its content accessibly is one that is resilient to change. The ability to easily screen-scrape HTML sites has led to some of the most interesting and useful applications online.

Where an accessible app out often matures into something of a loosely coupled data source toward its end of life, walled gardens of Java, ActiveX, Flash, and/or Silverlight are too opaque to offer that lasting benefit after they’ve become dated.

(un)Bonus: Mobility

Speaking of accessibility, take a look at this same site on an iPhone, which has arguably the best default mobile browser currently available:

Attempting to view Thrive Dev on my iPhone

HTML 5, CSS3, and JavaScript are probably the future for several classes of mobile applications. In fact, mobile support can be as easy as dropping in a new view for each device. Something like the (awesome) Chipotle iPhone app could just as easily be a mobile view using jQTouch.

With the growing ubiquity of devices like the iPhone, Palm Pre, and Android-based handsets, catering to mobile browsers is becoming an important consideration. Even if it’s still a minority use case (for now), users gravitate to sites that do work well with their mobile devices in that occasional pinch.

Maintainability

Long-term maintenance is a critical consideration when using plugin-based tools.

Think about all of the decade-old web applications that your business or clients are still keeping alive today. How many of them encapsulate important functionality within ActiveX controls? Probably almost none, and there’s a good reason for that.

These monolithic rectangles rot at a frightening rate. Maintaining plugin-based functionality entails more friction and a less widely available skill set than updating HTML markup, tweaking a CSS stylesheet, or changing a JavaScript include. More often than not, these opaque rectangles simply fall by the wayside over time, and might as well be chunks of the website written in COBOL.

POWERED BY COBOL ON COGS!

If segregating functionality into plugin-based walled gardens was a good idea, we’d still be using Java applets for rollovers in navigation menus.

Silverlight and WebForms aren’t the problem

To be perfectly clear, I think Silverlight is great.

Given the choice between Flash or Silverlight video, I’ll choose Silverlight every time. The video playback is smoother and Microsoft’s great development tooling tends to encourage feature-rich player applications. Even with HTML 5’s <video> element, browser-native video can’t currently compete with Silverlight.

Given the choice between developing an internal dashboard in Flash or Silverlight, I’ll choose Silverlight every time. The charting controls already available even after Silverlight’s short time on the market are awesome, and only getting better. HTML 5’s <canvas> may eventually become the best solution for this, but it’s going to be years before that’s a feasible reality.

There are plenty of scenarios where I think Silverlight is perfectly valid. Though it might be easy to take it that way, this is not an anti-Silverlight (or Microsoft) post.

In fact, I think WebForms is fine too.

Used responsibly, WebForms is still a useful and productive abstraction – especially with the great improvements coming in ASP.NET 4.0. There are plenty of times when something like Dynamic Data to scaffold an administration interface is a smart choice.

Conclusion

Bottom line? You should use idiomatic HTML, CSS, and JavaScript if they are at all able to accomplish what you’re trying to do. Embrace the platform.

More specifically, not wanting learn JavaScript is not a valid excuse for pretending it isn’t the Lingua Franca of the web. Many even find, to their surprise, that they enjoy JavaScript once it’s paired with a library like jQuery to abstract away the DOM. Using the tools currently available, it’s easier than ever to learn too.

Having keenly watched the ebb and flow of web technologies over the past fifteen years, I’m comfortable predicting that an investment in learning the underlying basics is crucial if you’re serious about developing for the web. Anything used to avoid this fundamental understanding is a crutch, not a tool.

###

Originally posted at Encosia. If you’re reading this elsewhere, come on over and see the original.

Is Silverlight the new WebForms?

Using NSScanner to convert Hex to RGB Color

I’ve found that defining a custom UIColor using RGB values is a little counter intuitive compared to the more common hexadecimal notation used in CSS. This is particularly true if you want to define a color value in a file and don’t want to have to split it into three separate values.
For the most [...]

WP Like Button Plugin by Free WordPress Templates