The jQuery Template Markup Language (JTML) Project

Posted April 27, 2010 at 8:36 PM by Ben Nadel

Tags: Javascript / DHTML

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.




Reader Comments

Apr 27, 2010 at 9:31 PM // reply »
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.


Apr 28, 2010 at 4:32 AM // reply »
12 Comments

Pretty cool concept Ben.


Apr 28, 2010 at 7:12 AM // reply »
1 Comments

this idea is awesome !


Apr 28, 2010 at 7:45 AM // reply »
11,243 Comments

Thanks guys, glad you like it. If you have any ideas about it, please let me know.


Apr 28, 2010 at 9:53 AM // reply »
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


Apr 28, 2010 at 9:56 AM // reply »
11,243 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.


Apr 28, 2010 at 10:07 AM // reply »
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 :)


Apr 28, 2010 at 12:18 PM // reply »
11,243 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.


Apr 28, 2010 at 5:27 PM // reply »
13 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


Apr 28, 2010 at 6:52 PM // reply »
11,243 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!


Apr 28, 2010 at 7:03 PM // reply »
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.


Apr 29, 2010 at 2:01 AM // reply »
13 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


MW
May 7, 2010 at 3:55 PM // reply »
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.


May 7, 2010 at 8:53 PM // reply »
11,243 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.


May 9, 2010 at 12:42 PM // reply »
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.


May 10, 2010 at 9:49 PM // reply »
11,243 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.



Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
May 22, 2013 at 5:35 PM
Script Tags, jQuery, And Html(), Text() And Contents()
This is still an issue 2 years later. jQuery is supposed to remediate these cross browser issues, no? I have been unable to find any statement from the jQuery team calling this behavior "by de ... read »
May 22, 2013 at 12:44 PM
Ask Ben: Query Loop Inside CFScript Tags
In cf10, if you call a function that has: local.result = {}; local.result.msg = ""; local.svc = new query(); local.svc.setSQL("SELECT * FROM..."); local.obj = local.svc.exe ... read »
May 22, 2013 at 12:29 PM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@Ben: What version of Java are you using? Also, did you test users.id to see what Java reports as the data type? I wonder if it's not a Java primitive data type, but getting returned as something ... read »
May 22, 2013 at 11:47 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@Dana, Awesome - so it looks like this bug was fixed in ColdFusion 10. Thanks so much for double-checking that. ... read »
May 22, 2013 at 11:37 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
When I c&p and run on cf10, I get: Selected User IDs: 1,4 User 1 selected: YES - YES User 2 selected: NO - NO User 3 selected: NO - NO User 4 selected: YES - YES User 5 selected: NO - ... read »
May 22, 2013 at 11:27 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@Tom, Good thought, but no dice. Both of these still exhibit the same behavior: users.id[ users.currentRow ] users[ "id" ][ users.currentRow ] It's just something whacky happening with ... read »
May 22, 2013 at 11:07 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
Could your problem be that "users.id" is actually an ARRAY, not a single value? Perhaps try it again with "users.id[1]" (I only have CF8 here at work). ... read »
May 22, 2013 at 7:52 AM
Nested Views, Routing, And Deep Linking With AngularJS
Hi, Just a quick thank you. As it happens, for my own purposes, the pending ui-router work being done in native angular is likely the one I'll adopt, but your exploration, code and documentation of ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools