jQuery Forum

jQuery Templates Proposal

by 
 on 26-Feb-2010 10:43 PM.
Hi Everyone,
 
We've put together a proposal for adding template support to the jQuery library and we would like your feedback. The proposal is posted here:
 
 
Our motivation for adding templating support is to make it easier to display database data when working with jQuery. For example, we want a standard jQuery method for displaying a set of product records retrieved from a database.
 
The proposal has two main sections. In the first section, we provide a brief review of existing templating solutions. We discuss Resig's micro-templating engine, jTemplates, PURE, and ASP.NET Ajax templates (this list of template engines, by no means, is meant to be comprehensive).
 
Next, we present our templating proposal. We suggest creating a new method named renderTemplate() that can either render a single JavaScript object or an array of JavaScript objects by using a fragment of HTML as a template.
 
Looking forward to hearing your feedback!
 
  -- Stephen Walther
  • No status
  • We'll think about it
  • Implemented
  • In-progress
  • Maybe later
  • Will not implement
  7 users like this idea 

Re: jQuery Templates Proposal

by 
 on 27-Feb-2010 04:58 PM
The roadmap has templating on the list for 1.5; I would like to see something small/simple to encourage its use versus the typical practice of having lots of html fragments in Javascript code.

I also like the idea of having {{= }} escape HTML by default, for safety. What if there was a separate one-character notation for unescaped substitutions, like {{! }} for example? I am hoping the ! might flag to people that they should think before using it.

> Note however that it is invalid to refer to a field that may not exist.

I am assuming that this is so the implementation can use the with(obj){} trick that John's templating uses. I always seem to end up with objects that have missing/optional fields. It should be fine to use something like ($dataItem.missing || "") where "missing" is a field that doesn't exist? Is this common enough that we need a shorter syntax?

Would it be kosher for the rendered functions to augment $context with their own data? I am thinking about templates where the final row" might be a sum of the previous columns, or where each row has a column that is a running total of the rows above it.
1 user thinks this adds value to idea.

Re: Re: jQuery Templates Proposal

by 
 on 27-Feb-2010 07:46 PM
Hi, thanks for the reply. I was also involved in creating the templating proposal.

What if there was a separate one-character notation for unescaped substitutions, like {{! }} for example?

Certainly easy enough to do. But I think allowing for html will be the exception to the rule, and a more advanced scenario, so if you have to go to a codeblock and wirteHtml(), I think that's acceptable enough. The advantage to just writing writeHtml, or whatever, is that you don't have to know about 2 different things depending on whether you are in a {{= }} block or a {{ }} block. And perhaps it is possible, even if unlikely, that the character would be ambiguous with the intended code. Perhaps the code in the code block happens to start with the not operator, as in {{!.....}}? Since it is a statement, not an expression, maybe that's not a concern, but its still possible you'd want to start off a statement with "!", or whatever char was used.

> It should be fine to use something like ($dataItem.missing || "") where "missing" is a field that doesn't exist

Yeah. Although not everyone would understand why {{= optionalField }} causes an error. How much of a pitfall that is I'm not sure. Debugging into generated code is tricky in many debuggers. Having another syntax for doing this is an interesting thought. But that might only solve part of the problem, since someone might still use the field in a code block, such as in {{ if (optionalField) { }}, which would still be a problem. Perhaps this kind of thing is best addressed via awareness/docs.

> Would it be kosher for the rendered functions to augment $context with their own data?

I'd say, absolutely. The context is born to be played with. The function which creates the template is called once for each dataitem, so it is a logical way for them to share data, such as a running total like you said. Actually appending data to the data array is an interesting thought. To support that, the implementation would have to avoid caching the length of the array, just in case, and you'd only be able to append data to a point after the current index. Not caching the length would hurt performance a bit.
1 user thinks this adds value to idea.

Re: jQuery Templates Proposal

by 
 on 02-Mar-2010 08:56 PM
Hi everyone,
 
We've updated the templates proposal in response to feedback:
 
 
For example, we've added a new set of delimiters [[! ... ]] for displaying unescaped HTML. We've also added support for a rendering() function that gets called before each template instance is created.We also renamed the renderTemplate() method to template().
 
We would like to get additional feedback.Do the current set of delimiters make sense? Are we missing crucial functionality? Are there any features that you would remove?
 
  -- Stephen Walther
 

Re: Re: jQuery Templates Proposal

by 
 on 02-Mar-2010 11:14 PM
Hey, Stephen, you had me convinced that the unescaped HTML sequence might be a bad idea! I read it through again and had a few other thoughts.

The example of the template with a rendered() makes sense with the explanation above it, but there are several mystical things about it. The specialness of the name "rendered" seems odd. Unlike most jQuery usage the "this" is a jQuery object rather than a DOM element (plugin authors are used to that but most template users won't be). The $context object isn't an argument to the function, although it could be passed in. I wonder if the template rendered() could be left out.

Related to the discussion about declaring event handlers, I am more likely to use event delegation with template-rendered code because it's generally a lot of rows/elements and I don't want to attach individual event handlers on all of them. When that's the case I don't think I'd want code in the template at all. For example, I'm filling in a table where the table, thead, and tbody elements are outside the template, and the tempate is the tr elements inside the tbody. The event handers are attached to the tbody and events bubble up from the rows.

We need some other opinions! It would be good to get input from some users of the other templating code and see what they do/don't use.

Re: jQuery Templates Proposal

by 
 on 03-Mar-2010 12:31 AM
the unescaped HTML sequence might be a bad idea

Perhaps -- I'm on the fence about it. The one thing not obvious from this update is that we removed write() and writeHtml() for simplicity, so the HTML-allowing expression syntax is currently the only way to output known html. Which do you think is better -- a write/writeHtml "special" function or the syntax?

> The specialness of the name "rendered" seems odd

True it just a convention. It could be done in a more traditional way by setting something on the $context, like $context.rendered(function() { }), or $context.rendered = function() {}. Is one really better than the other? Which would you choose?

> "this" is a jQuery object rather than a DOM element (plugin authors are used to that but most template users won't be)

Hmm. I'm coming from more of a plugin authoring side. This is true of the rendered callback from the call to template() as well though (in fact, the inline rendered function is just an implied handler to that callback). I can't see any other way though, you need that context of dom elements to restrict any queries or operations to them, where you are attempting to do something that is unique to the current data item.

> The $context object isn't an argument to the function, although it could be passed in.

Yeah it's available simply because the rendered function exists as a closure within a dynamically created function created from the template. That shouldn't be too surprising since you have access to $context in expressions and code blocks, and the function is also in a code block. But yes, it could be passed in as a parameter, too.

> I wonder if the template rendered() could be left out.

Perhaps. Although I quite like the idea of the template being fully self-describing, and then used in a very semantic way in the code. Especially because one scenario I know comes up often in templating solutions is the ability to use 'external' templates, by loading them dynamically from separate files or what-not. That lends itself well to reusing templates across different pages (which also carries the advantage of being separately cached by the browser, although with the trade-off of an additional request). If it is a template that requires a little code to situate it, it would be a shame to have to duplicate that code in different pages (even if it is in the form of a packaged function).

> RE event handlers

Agreed, it would be better to write code even if you needed it. This thread is the discussion now, so I suppose we should just remove that section in the proposal. Thanks so much for your feedback, it's good stuff!

Re: jQuery Templates Proposal

by 
 on 04-Mar-2010 11:03 PM
Thanks for bringing this discussion up - we definitely want to land something good in core and there are a lot of good suggestions here.

I want to discuss the API first and then we can move on to discussing the actual templating language. Going forward I'm assuming that 1) You will be able to plugin different templating engines and 2) That we'll try to ship a very simple templating scheme that matches the expectations of most our users while still leaving room open to further exploration.

Some points about the API proposed:

  1. I liked your method of extracting templating logic from existing script elements on the page. This should be baked in to the initial implementation as it makes a lot of sense.
  2. The current proposal only has a way to directly inject some HTML into the page (using .html()). This removes much of the flexibility of DOM manipulation in jQuery. There needs to be, at minimum, a way to generate a templated node that can be injected elsewhere, later, and a way to inject a node dynamically (using append, etc.) while still having access to the templating layer.
  3. I like the proposal of having a cache where named templates can be stored and easily retrieved. I think we should probably require that any templates in there are pre-compiled (to save later checks and compilation steps).
  4. I'm not sure I understand the benefit of the callbacks in the proposal - do you have any examples of where they might be used?

Some points about the templating language:

  1. I'm not a huge fan of the {{ ... }} syntax - it seems like, especially in the context of JavaScript, there are cases where that could result in ambiguous templates. For example: "{{ data = {user:{name:'John'}}; }}". In the case of my micro templating syntax it's very hard for there to be potential conflicts.
  2. I think the default method that prints content out (named 'write' or 'print' or whatever) should allow HTML by default and only encode the output when requested. Perhaps the methods could be named 'html' and 'text' (to coincide with the jQuery methods of the same name).
  3. I'm not seeing the particular merit of nested templates - are there any other examples?
  4. Having $dataItem and $index (or similar) seems quite useful - didn't think of that previously.
  5. I see the merit of $id() (and similar functions) although I don't think that that's something that we'd ship in the default implementation - having a way to easily snap in new functions would be really nice. (jQuery.tmplFn.$id = ...;)

To start discussing, and better understand, the API I took many of the suggestions that you put forward and started to draft up how the API would work. To better understand how the API would function I created a plugin version of the code to start playing around with the result (I used my micro templating plugin for now).

jQuery Templating Plugin:
http://github.com/jquery/jquery-tmpl

I've implemented virtually everything in your proposal, plus my additions. Only one point is currently missing: It's not entirely clear how 'this' would work in my implementation - or what it would refer to.

Hope this code can give us something to start playing around with and get a feel for if this API makes sense and how we should proceed from here.
5 Users think this adds value to idea.

Re: Re: jQuery Templates Proposal

by 
 on 05-Mar-2010 02:05 PM
john, i think that micro-template format, while very flexible due to intermixed js, is damn near impossible to read, and even the demo, that is something very basic, is already a huge mess.

not only do ASP style delimiters interfere on the server-side, they also screw up 99% of syntax coloring editors by interpreting ASP and making the template a rainbow mess that neither shows markup structure (or coloring since it is inside script tags) nor its construction well at all.

i would certainly say pull the templates out of the script tags, templates are much closer to markup than script. the user should be smart enough to add display:none to the template holder or some .tpl class. this at least would retain markup highlighting. for script constructs, maybe change the delimiter to something that doesnt cause editors to barf ASP colors. maybe <[ or <#

Edit: thinking about it, <[ would prolly interfere

i understand the need for ultimate flexibility, but template designing will be a PITA with this micro-template format. sacrificing some flexibility is well worth having templates with a much more clear html structure that accommodates most users.

in the long run you can make this micro-templating parser as a plugin that overrides some more basic parser rather than having one that allows everything but with crazy looking templates that you might as well use notepad to create and edit.

i'm of the opinion that you should be able to copy/paste a template into a blank <body> tag (with appropriate css, images, etc) and see basically how it lays out without needing for it to be entirely assembled via script, a templating script should only do variable insertions, iterations, maybe subtemplate insertions.

$0.02
1 user thinks this adds value to idea.

Re: Re: jQuery Templates Proposal

by 
 on 05-Mar-2010 02:33 PM
What you propose is fine (having the markup be inline) - but I have yet to see a sane templating language that transforms existing markup into a new output that doesn't use XSLT or XPath. I'm definitely open to suggestions. One that uses data-* attributes from HTML 5 might be interesting if there was a way to do it without becoming too convoluted. While in theory I tend to like having real markup/DOM be transformed into other DOM structure in practice I find it to be clunky and cumbersome - which is why I'm leaning more towards supporting inline scripting.

As to the specific syntax of the templating language, I'd be fine changing it to {% ... %} (for code blocks) and {{  }} (for values). That's closer to what was proposed and matches Django-style templates. Currently I'm using Ruby (erb) style templating syntax. Sorry that the current syntax "barfs" in ASP but I suspect that any templating syntax that we pick will "barf" in some server-side syntax-highlighter somewhere - we'll need to standardize on something - and that might as well be an existing templating syntax.

Re: jQuery Templates Proposal

by 
 on 05-Mar-2010 05:51 PM
kind of interesting that this came up today on dailyjs.com:
http://haml-lang.com/
 Back
 Top
Post Actions
Statistics
  • 9
     Replies
  • 488
     Views
  • 9
     Followers
Tags for the post
No tags available for this topic.

Edit Link Delete Link

Edit Link Delete Link

LoadingImage