Skip to main content
Ben Nadel at the New York ColdFusion User Group (Feb. 2009) with: Joakim Marner and Clark Valberg
Ben Nadel at the New York ColdFusion User Group (Feb. 2009) with: Joakim Marner Clark Valberg ( @clarkvalberg )

The jQuery Template Markup Language (JTML) Project

By on

After this morning's post about my jQuery Template Markup Language (JTML) concept, I added a bit more functionality and gave JTML its own project page. Now, I can start adding and refining functionality as I think of it. If you missed the earlier post, JTML provides an easy way for jQuery developers to populate HTML templates with both simple and complex, nested data structures. It uses a friendly, tag-based syntax that seamlessly integrates with your existing HTML markup allowing you to create rich, dynamic interfaces with little effort.

There are currently three supported tags in the JTML specification:

<jtml:if test="condition">
<jtml:else [ test="" ]>
</jtml:if>

The If/Else tag allows you to conditionally render parts of the HTML template. In its most basic form, it is simply an if-else control flow. The Else tag, however, can take an optional Test attribute, providing more logic to the control flow. You may have as many else/test tags as you like within each if tag.

<jtml:loop index="i" collection="" [ key="" ]>..</jtml:loop>
<jtml:loop index="i" to="" [ from="" step="" ]>..</jtml:loop>

The Loop tag allows you to uniformly loop over collections whether they are arrays or object maps. With each iteration, the Index value contains the object of the key (which is, itself, an optional attribute). The Loop tag also allows for standard index loops, which default to start at zero.

<jtml:include template="selector" />

The Include tag allows you to include other JTML templates directly into the current template control flow. The Template attribute is a jQuery selector that will be used to locate the target template on the page. Once located, the JTML of the included template is extracted and executed within the current template.

${variable}

While not a JTML tag, the ${..} notation allows you to render variable values within the JTML template. This is how the Javascript data ultimately becomes part of the rendered HTML output.

I only started playing around with the jQuery Markup Template Language (JTML) last night, so the project is still very raw; if there is anything you'd like to see or anything you think will add value, please let me know.

Want to use code from this post? Check out the license.

Reader Comments

5 Comments

Awesome, Ben, and thanks! I'll be playing with this tomorrow ... my current project requires tons of reused templates populated by JSON'd CFC beans (well, their mementos, anyway). Between corMVC and this, I'll owe you quite a few beers at CFUnited.

1 Comments

Hi Ben,

This looks great - its definately the most intuitive templating I have seen for Javascript.

Did you know Microsoft is sponsoring/working on a templating functionality for Jquery - yours looks much better to me :D

15,666 Comments

@Diarmuid,

I saw that Microsoft was working on something. I think I saw a very brief demo of it somewhere. To me, it just comes down to syntax; tags are so nice and easy to understand and, coming from an HTML / ColdFusion background, they make so much sense.

34 Comments

Ben,

I have to say not a fan of templating as it generally adds a layer (might be my experience with PHP templating systems that taints --hmm play on word--- my opinion). But I think if templating is really restricted to key uses (they mention plugins, if/else statements, etc..) then I can see benefit to learning one more thing.

I will say I like the approach you took. When using a syntax similar to HTML/Coldfusion you really reduce the learning curve and make it more readily usable. It reminds me of when CFSCRIPT went from a CF/ECMA hack to being more a "true" ECMA script, which allows less mental language switching and speeds development.

I think you should push this early stuff how into the wild and get feedback from the jQuery community. There are a lot of techies out there and before your know it there will be some silly schemas (Smarty tags anyone, yeah I said it)

Look forward to more postings on this and just one more thing to add to read list :)

15,666 Comments

@Kevin,

Thanks my man. I know even in the ColdFusion world, there are people who use things like Java and Groovy to do all the domain modeling and the business logic, but still prefer to use ColdFusion as the template system. I think there's a lot of merit to a tag-based rendering system.

But, I agree with you, on the client side, this kind of thing only makes sense in some key use cases.

So far, getting some good feedback. Next, maybe I'll try to make a tiny demo of client-server communication that uses this approach.

14 Comments

Hey Ben, great blog - been a follower for some months now.

I got inspired by your markup language approach and have a few comments.

How about writing variables like so
<jtml:var name=variable /> instead of ${variable}

I could see this syntax being extended like so
<p>Error: <jtml:var onEmptyRMNode=p name=errmsg /></p>
Which would remove (<p>.*</p>) if errmsg is empty

Also a nice template engine should have a good handling of node attributes. I just don't have a clue to how the syntax should be ...

without looking this ugly...

<img title="[jtml:attr onEmptyCollaps name=attribute /]" />

a <jtml:fun /> function call might also be a nice extension

15,666 Comments

@Morten,

For outputting variables, I wanted to try to avoid tags only because I felt like it adds too much weight. I've worked with a few different server side languages and I personally find the ones with less variable output syntax more pleasing. My favorite language right now is ColdFusion, and they actually use less syntax:

"something something #var# something"

I would have considered that, except if my page was ColdFusion, i'd have to escape them just to render the HTML page :)

Groovy uses the dollar sign in its string, I think:

"something something $var something"

This is cool; but, there's actually something nice about surrounding the variable with two things, as in ${}, because it gives you a bit more control over how the variable gets interpreted.

Of course, tagging would give you a lot of control as well; but, I guess I hated ASP for long (college) where you have to use stuff like:

<%= var %>

.. that when I saw how simple it was in ColdFusion (#var#) it just made me super happy :)

I know that's a very *emotional* way to design something... but, that said, I'd like to hear more about your other two ideas. I don't quite follow them completely. Can you expand a bit? Thanks!

5 Comments

I have to agree completely with avoiding the 'weight', otherwise you just end up creating another XSLT/SOAP etc. bloated protocol that tries to deal with everything (like a self-validating JSON project I saw a few months ago ... eeek!). Nothing simpler than a few <jtml> control tags surrounded by good old html.

14 Comments

My suggestions was not so much concerning syntax as it was features.

<p>Error: <jtml:var onEmptyRMNode=p name=errmsg /></p>

would be the same as

<jtml:if test="!empty(errmsg)">

<p>Error: ${errmsg} /></p>

</jtml:if>

onEmptyRMNode points to a parent node. So you could have

<div>Error: <span><jtml:var onEmptyRMNode=div name=errmsg /></span></div>

Now for attributes I think my suggestion really shows it's weight friendliness

<img ... title="[jtml:attr onEmptyCollaps name=attribute /]" />

compared to

<jtml:if test="!epmty(attribute)">

<img ... title="${attribute}" />

<jtml:else>

<img ... />

</jtml:if>

As for the syntax I have no problem with doing

${option option option #variable}

that would make it easier to put in attributes

1 Comments

Ben, great work. This model copuled with all the other great JS frameworks/plugins will make client side dev. immensely powerful.
I'm sure you're aware of SPRY framework's constructs(tags) for working with datasets. I hope you'll incorporate some of their ideas.

15,666 Comments

@Morten,

I think I see what you're saying. I just need to wrap my head around it, let it simmer for a while.

@MW,

I'm glad you brought up Spry. I've looked at some examples, but I think without really diving into it, I wasn't quite understanding how it did some of the looping data population. If you have something specifically you'd like to see, please feel free to outline it here at @Morten did and we can do some brainstorming.

1 Comments

Ben, this is great stuff!

I found a bug that affects Chrome, but it's easily fixable. On line 51 of jquery.jtml.js, change

if ($1.length){

to

if ($1){

Chrome (at least in os x, havent checked windows yet) interprets $1 as undefined, rather than as en empty string (with a length of 0). This is in the markup.replace() function.

I've been using this pretty heavily to template api responses and it's awesome! I'll chime in if I find anything else...

word.

15,666 Comments

@Wookiehangover,

Thanks for pointing that out. It should be fixed in the latest build, if you check the project page. I also fixed some other cross-browser issues. I am super excited that you are already making use of this and finding it highly effective.

If you get any ideas, please let me know. I'm really looking forward to growing this project.

I believe in love. I believe in compassion. I believe in human rights. I believe that we can afford to give more of these gifts to the world around us because it costs us nothing to be decent and kind and understanding. And, I want you to know that when you land on this site, you are accepted for who you are, no matter how you identify, what truths you live, or whatever kind of goofy shit makes you feel alive! Rock on with your bad self!
Ben Nadel