Move this topic
jQuery Templates Proposal
In-progress
- Maybe later
- Under review
- In-progress
- Implemented
- Will not implement
in Developing jQuery Core
•
11 years ago
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
29
Replies(94)
Re: jQuery Templates Proposal
11 years ago
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.
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.
Re: Re: jQuery Templates Proposal
11 years ago
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.
Leave a comment on dave.methvin's reply
Re: jQuery Templates Proposal
11 years ago
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
11 years ago
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.
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.
Leave a comment on stephen.walther's reply
Re: jQuery Templates Proposal
11 years ago
> 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!
Leave a comment on infinity88's reply
Re: jQuery Templates Proposal
11 years ago
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:
Some points about the templating language:
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.
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:
- 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.
- 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.
- 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).
- 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:
- 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.
- 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).
- I'm not seeing the particular merit of nested templates - are there any other examples?
- Having $dataItem and $index (or similar) seems quite useful - didn't think of that previously.
- 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.
Re: Re: jQuery Templates Proposal
11 years ago
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
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
Re: Re: jQuery Templates Proposal
11 years ago
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.
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: Re: jQuery Templates Proposal
11 years ago
I have a few problems with using JavaScript directly like this:
- Complex logic should not be put into templates. My feeling is that most modern designs try to discourage this by providing what amounts to a crippled language subset. Object assignments, like the one you used as an argument against curly braces, do not belong in the template.
- Templates become unreadable. Does anybody really want curly braces in templates?
- Templates become strict.
- Templates become hard to debug.
I feel that template systems need to be able to suppress lookup errors; preferably with a setting.
- <%= foo.bar %>
If foo is null, then the templating system bombs out. Users may have reasonable expectations for it to return "". In this case the system will throw a "foo is null" error - which is fine I guess. What happens when this is an IE specific error, like a trailing comma?
My preference is for less javascriptyness in favor of something simpler, where most of the work is done by the methods in tmplFn.
- tmplFn: {
- "each": function() {
- // ...
- },
- "if": function() {
- // ...
- }
- }
Leave a comment on jeresig's reply
Leave a comment on leeoniya's reply
Re: jQuery Templates Proposal
11 years ago
I wasn't aware this was being developed, so I apologize for the way in
which I've had to do it myself as a relative newcomer to jQuery.
The plugin I'm writing is not designed to generate new HTML from spec. What it does instead is take existing DOM elements which are hidden from the user and clone them, making several user-specified alterations along the way, then insert it into the destination. If a template element has class 'enum', then a postfix with an index number is attached to any ID/name attributes which are present in the cloned element. Selectors passed to the plugin define which elements are to be hidden or removed. Add/Remove button classes are part of this along with the logic to enable/disable them if optional minimum/maximum clone values are met.
I am not a fan of hiding templated elements in either script blocks or worse, textareas. It encourages web designers to treat their work as hacks rather than enhancements. CSS does a capable enough job of hiding the original templates, and the validate plugin can remove them all before the form is submitted. Were I more competent I would make this plugin cache all the template items at document ready and then delete the HTML elements from the DOM.
The only thing I am struggling with right now is the best way to tokenize variable string content.
Demo is here: the plugin in progress is here. Feedback is appreciated.
The plugin I'm writing is not designed to generate new HTML from spec. What it does instead is take existing DOM elements which are hidden from the user and clone them, making several user-specified alterations along the way, then insert it into the destination. If a template element has class 'enum', then a postfix with an index number is attached to any ID/name attributes which are present in the cloned element. Selectors passed to the plugin define which elements are to be hidden or removed. Add/Remove button classes are part of this along with the logic to enable/disable them if optional minimum/maximum clone values are met.
I am not a fan of hiding templated elements in either script blocks or worse, textareas. It encourages web designers to treat their work as hacks rather than enhancements. CSS does a capable enough job of hiding the original templates, and the validate plugin can remove them all before the form is submitted. Were I more competent I would make this plugin cache all the template items at document ready and then delete the HTML elements from the DOM.
The only thing I am struggling with right now is the best way to tokenize variable string content.
Demo is here: the plugin in progress is here. Feedback is appreciated.
Re: Re: jQuery Templates Proposal
11 years ago
i'm actually doing something near-identical with a plugin that i am writing as well. there is a single entry form and a table of records beside it. once the form has been entered and the user presses Save, the data is gathered, stored in a JS object and rendered out into a clone() of a template row and appended to the tbody.
the locations of the values it populates into the template are hardcoded for now, i've been meaning to just have something like {price} inside the template's tds and use .text() to replace it with record data. in my situation, a curly brace will never be encountered in a template context for other purposes. i'm a big fan of using clone() as a templating method
the locations of the values it populates into the template are hardcoded for now, i've been meaning to just have something like {price} inside the template's tds and use .text() to replace it with record data. in my situation, a curly brace will never be encountered in a template context for other purposes. i'm a big fan of using clone() as a templating method
Re: Re: jQuery Templates Proposal
11 years ago
John says two years ago in his initial MicroTemplate blog post:
John's hack above relies on the assumption that a valid content-type used outside its intended context will prevent a user agent from interpreting enclosed content: content which is partially conformant to that content-type, content unwrapped by <![CDATA[ ]> or any comment characters and therefore only blocked from rendering/executing by a vendor's choice of contextual restrictions set in software. For now, it works without negative consequences.
To those who think I'm being a nanny, there has already been at least one security advisory that came as a result of OBJECT elements with TYPE "text/html" inside IE.
What John didn't find out when writing his MicroTemplate code was that TYPE attributes which refer to content-type don't require IANA-registered content-types, and user agents are expected to do nothing if they don't recognize the content-type.
Templates being neither HTML nor JavaScript/jQuery proper meet the definition of a private encoding, which means according to IETF it's perfectly valid to give them a private encoding like "text/x-jquery-template". Because it's private, there is no requirement that this "x-" namespaced encoding have a DTD, RFC or other normative document. That's not a hack, that's how data formats not to be natively parsed are meant to be identified.
Even if this were a guaranteed non-issue, I would strongly suggest that instead of misusing SCRIPT as a container element for mostly non-script content, that STYLE be used, as the purpose of STYLE (content presentation) is philosophically closer to what templating intends to achieve (think of the before: and after: CSS2 pseudoselectors).
As proof, with John's own MicroTemplate code, the container tag
The only non-philosophical difference is that STYLE is restricted to living inside the HEAD element, which is semantically and structurally the most appropriate location for a template element when you consider the W3's definition of HEAD (emphasis mine):
This makes baby Jesus cry. The contents of the SCRIPT element are and always have been treated as a string (more accurately, CDATA) regardless of what the TYPE attribute (or default script type) says. TYPE defines what parser gets to interpret it.Notice that the SCRIPT element’s type attribute has the value “text/html”. Web browsers ignore the contents of SCRIPT elements declared in this way and treat the contents of the SCRIPT element as a string.
John's hack above relies on the assumption that a valid content-type used outside its intended context will prevent a user agent from interpreting enclosed content: content which is partially conformant to that content-type, content unwrapped by <![CDATA[ ]> or any comment characters and therefore only blocked from rendering/executing by a vendor's choice of contextual restrictions set in software. For now, it works without negative consequences.
To those who think I'm being a nanny, there has already been at least one security advisory that came as a result of OBJECT elements with TYPE "text/html" inside IE.
What John didn't find out when writing his MicroTemplate code was that TYPE attributes which refer to content-type don't require IANA-registered content-types, and user agents are expected to do nothing if they don't recognize the content-type.
Templates being neither HTML nor JavaScript/jQuery proper meet the definition of a private encoding, which means according to IETF it's perfectly valid to give them a private encoding like "text/x-jquery-template". Because it's private, there is no requirement that this "x-" namespaced encoding have a DTD, RFC or other normative document. That's not a hack, that's how data formats not to be natively parsed are meant to be identified.
Even if this were a guaranteed non-issue, I would strongly suggest that instead of misusing SCRIPT as a container element for mostly non-script content, that STYLE be used, as the purpose of STYLE (content presentation) is philosophically closer to what templating intends to achieve (think of the before: and after: CSS2 pseudoselectors).
Moreover, adding an ID attribute to a SCRIPT element breaks validation in all variants of HTML; ID is exclusive to BODY and its children. While SCRIPT has no comparable attribute, STYLE has TITLE; a templating engine could copy this value at initialization and attach an ID attribute to the element, keeping the functionality while the code itself passes validation:
Internally, the two elements are nearly identical according to the DTD; they are CDATA wrappers whose content is passed off to a parser chosen by the TYPE attribute.- $("style").each(function(){$(this).attr("id",$(this).attr("title"));});
As proof, with John's own MicroTemplate code, the container tag
- <style title="MyTemplate" type="text/x-jquery-template">
- <script id="MyTemplate" type="text/html">
The only non-philosophical difference is that STYLE is restricted to living inside the HEAD element, which is semantically and structurally the most appropriate location for a template element when you consider the W3's definition of HEAD (emphasis mine):
To sum up:The HEAD element contains information about the current document, such as its title, keywords that may be useful to search engines, and other data that is not considered document content. User agents do not generally render elements that appear in the HEAD as content. They may, however, make information in the HEAD available to users through other mechanisms.
- Templates are a conduit for content presentation. STYLE is about presentation of content and CSS continues to evolve closer towards templating.
- Don't hide this templating language with a hack. If content-types are to be used to block content from a native parser, then follow the IANA's convention for unstandardized encodings; a custom content-type prefixed by "x-" (not "X-"). Using existing content-types outside of their intended context is unnecessary and misrepresents the contents and could cause future problems.
Re: Re: jQuery Templates Proposal
11 years ago
Yeah, using script tags to pass templating data is a clever hack at best. Similarly is passing template data in comments. While browsers themselves may be fine with this, I would never ever risk using it because I have looked upon the havoc proxies and "security" and other sanitizers have wrecked.
My gut feeling is that this will cause a world of pain down the line.
Re: Re: jQuery Templates Proposal
11 years ago
Nothing in my implementation - or even in the original Micro Templates proposal - necessitates the use of script elements or even a specific content-type. In the plugin that I proposed it's simply retrieving the innerHTML of an element - that could be a script element, a style element, a textarea, or even just a regular element.
Even so, there is absolutely nothing wrong with use of script elements for this purpose - its use in this case is even outlined in the HTML 5 specification:
http://www.w3.org/TR/html5/semantics.html#script
"The
So not only will the contents never be executed but it's also semantically correct - we're including templating data inside the script elements with a proper MIME type to denote the contents. I'd have no problem recommending a MIME type like "text/x-jquery-template" in this case.
Even so, there is absolutely nothing wrong with use of script elements for this purpose - its use in this case is even outlined in the HTML 5 specification:
http://www.w3.org/TR/html5/semantics.html#script
"The
script
element allows authors to include dynamic
script and data blocks in their documents... When used to include data blocks, the data must be embedded
inline, the format of the data must be given using the type
attribute, and the src
attribute must not be
specified... The type
attribute gives the language of the script or format of the data. If
the attribute is present, its value must be a valid
MIME
type."So not only will the contents never be executed but it's also semantically correct - we're including templating data inside the script elements with a proper MIME type to denote the contents. I'd have no problem recommending a MIME type like "text/x-jquery-template" in this case.
Leave a comment on andrew.roazen's reply
Re: jQuery Templates Proposal
11 years ago
i also pointed out previously that <script> is probably not an appropriate container for templates.
your points are certainly valid, but these are very simple changes which can be ironed out AFTER the template structure itself is decided upon, i dont think MicroTemplates have all the votes just yet, lol
in the meantime here's another link to throw into the mix:
http://ajaxpatterns.org/Browser-Side_Templating
your points are certainly valid, but these are very simple changes which can be ironed out AFTER the template structure itself is decided upon, i dont think MicroTemplates have all the votes just yet, lol
in the meantime here's another link to throw into the mix:
http://ajaxpatterns.org/Browser-Side_Templating
Leave a comment on leeoniya's reply
Re: jQuery Templates Proposal
11 years ago
John says:
The Validate plugin's method for creating and attaching custom rules would be my most likely inspiration for custom logic: it's elegant, it's standardized, and it separates logic from presentation.
Variable replacement is going to be either a tag's text contents or an attribute's text contents 99.9% of the time for me. Both can be handled with #-wrapped variable names without upsetting an IDE.
I found it to be neither in the plugin I'm writing. A hidden piece of markup is transformed based on classes and selectors, following the conventions of other jQuery features and plugins. The only thing it lacks currently is custom logic and variable replacement.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
The Validate plugin's method for creating and attaching custom rules would be my most likely inspiration for custom logic: it's elegant, it's standardized, and it separates logic from presentation.
Variable replacement is going to be either a tag's text contents or an attribute's text contents 99.9% of the time for me. Both can be handled with #-wrapped variable names without upsetting an IDE.
I think you're finding yourself in the minority here, especially amongst web developers who depend on their IDEs understanding syntax. When I implement jQuery to solve problems in record time, I look like a hero. When I have to to explain to my team why their IDE consistently highlights lines in a block as invalid markup, because a developer who doesn't spend most of his time making websites didn't think it was important enough to avoid, I look like a dumbass. Think less like a coder and more like a web developer who will reject any solution which breaks validation or most IDEs.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: Re: jQuery Templates Proposal
11 years ago
maybe the js ninja browses sites by telneting to port 80 and codes in notepad/pico? ; )
Re: Re: jQuery Templates Proposal
11 years ago
Andrew: The fact that you don't have any sort of custom logic or variable replacement in your solution yet is particularly damning - this is, by far, the hardest part of a good templating solution and one that, almost universally, will bloat the size, and confuse the implementation, of a pure-markup solution. I also disagree that the problem is as simple as you make it out to be (only replacing tag text content or attribute text content). If it were that simple then it's doubtful that you would even need a templating solution in the first place - you could just use a couple jQuery statements and be done with it.
Our options are to either 1) Use an existing templating format that users are familiar with (and that could possibly confuse syntax highlighting in an IDE) or 2) Use some cryptic never-before-seen templating format that may or may not interfere with the syntax highlighting of an IDE. It seems obvious to try and go with an existing format - both because users will already be familiar with it but also in that trying to figure out a new format, that is still somehow usable, is a Sisyphean task. As mentioned before, I'm open to using the Django-template-style of markup (or something similar), at least in that case there is less chance for IDE breakage as there are less IDEs that natively support that form of templating.
Our options are to either 1) Use an existing templating format that users are familiar with (and that could possibly confuse syntax highlighting in an IDE) or 2) Use some cryptic never-before-seen templating format that may or may not interfere with the syntax highlighting of an IDE. It seems obvious to try and go with an existing format - both because users will already be familiar with it but also in that trying to figure out a new format, that is still somehow usable, is a Sisyphean task. As mentioned before, I'm open to using the Django-template-style of markup (or something similar), at least in that case there is less chance for IDE breakage as there are less IDEs that natively support that form of templating.
Leave a comment on andrew.roazen's reply
Re: jQuery Templates Proposal
11 years ago
I'm still collecting my thoughts but I wanted to provide some early feedback.
I'm in favor of django-style {{ }} for tags and {% %} for blocks. Valid html, readable, not ugly, usable in IDE/editors (for example, editing an href or a title attribute in a properties grid). To me it has one of the principal advantages of Markdown - it's how you might write something in plain text anyway, for example, in a mockup:
I'm playing with John's prototype linked above, adding support for some django template tags and filters . I hope to post soon when I've got something usable.
I'm for limited capabilities rather than inline JavaScript. If we create a system like Django's, other than building on something that's proven and tested, we solve some major problems I see with inline JavaScript in template blocks:
- name collisions with local variables in template JavaScript and data members
- token collisions with JavaScript object literal syntax }} and template syntax }} (as John pointed out before)
- it's much easier for a template author/editor to read and write
- code reuse can increase and unit testing will be simpler when functionality/logic is placed in the template system javascript instead of that javascript code in the template block itself. This is in line with separating content from presentation from style from behavior, as we do well with unobtrusive JavaScript, semantic HTML, and CSS.
I'm in favor of django-style {{ }} for tags and {% %} for blocks. Valid html, readable, not ugly, usable in IDE/editors (for example, editing an href or a title attribute in a properties grid). To me it has one of the principal advantages of Markdown - it's how you might write something in plain text anyway, for example, in a mockup:
- Welcome {{ first_name }}, {{ last_name }}.
I'm playing with John's prototype linked above, adding support for some django template tags and filters . I hope to post soon when I've got something usable.
I'm for limited capabilities rather than inline JavaScript. If we create a system like Django's, other than building on something that's proven and tested, we solve some major problems I see with inline JavaScript in template blocks:
- name collisions with local variables in template JavaScript and data members
- token collisions with JavaScript object literal syntax }} and template syntax }} (as John pointed out before)
- it's much easier for a template author/editor to read and write
- {% for athlete in athlete_list %}
- <li>{{ athlete.name|capfirst }}</li>
- {% endfor %}
- {% for (var i=0; i < athlete_list.length; i++) {
- html('<li>' + capfirst(athlete_list[i].name) + '</li>');
- } %}
- code reuse can increase and unit testing will be simpler when functionality/logic is placed in the template system javascript instead of that javascript code in the template block itself. This is in line with separating content from presentation from style from behavior, as we do well with unobtrusive JavaScript, semantic HTML, and CSS.
Re: Re: jQuery Templates Proposal
11 years ago
I definitely agree that having a simplified templating language (such as the one that you pointed out) is much simpler and potentially easier to understand than having inline JavaScript. That being said it also thoroughly confuses the process by mixing a completely different language into jQuery itself - especially when jQuery works really hard to embrace the JavaScript language, as-is.
Perhaps a better solution would be one that embraces the idioms presented by jQuery itself to make the templates easier. Perhaps something like:
Perhaps a better solution would be one that embraces the idioms presented by jQuery itself to make the templates easier. Perhaps something like:
- {each athlete_list}
- <li>{{ this.name|capFirst }}</li>
- {end}
Leave a comment on rdworth's reply
Re: jQuery Templates Proposal
11 years ago
Hi everyone,
I like very much the idea of been able to create templates as specific parts of the page with jquery. I also agree with all the ideas of the thread, and only the standardization of the template is missing for me now.
I strongly believe that the most important part of the template functionality should be the ability to include and reuse templates from another templates, so the code will be kept clean and modular all the time.
Imagine for example a modal dialog. This is a functional part that can 'wrap' another templates / code or both. In the current examples there only the possibility to add templates through code, and I will agree that if the code will something complex then this will already become another chunk of non-readable code.
I would like to add something more to the template creation, the notion of the "template library". The template library is just a collection of templates, and my thoughts were around xml for this usage. This will also help each template to discover the way that will find the other (in a case of a lazy-load template system).
I have created an example of a template library that describes a tree structure with templates (at least try to be):
Thank you for reading!
I like very much the idea of been able to create templates as specific parts of the page with jquery. I also agree with all the ideas of the thread, and only the standardization of the template is missing for me now.
I strongly believe that the most important part of the template functionality should be the ability to include and reuse templates from another templates, so the code will be kept clean and modular all the time.
Imagine for example a modal dialog. This is a functional part that can 'wrap' another templates / code or both. In the current examples there only the possibility to add templates through code, and I will agree that if the code will something complex then this will already become another chunk of non-readable code.
I would like to add something more to the template creation, the notion of the "template library". The template library is just a collection of templates, and my thoughts were around xml for this usage. This will also help each template to discover the way that will find the other (in a case of a lazy-load template system).
I have created an example of a template library that describes a tree structure with templates (at least try to be):
- <script type="text/x-jquery-template-library" id="local-xml-library-definition">
<!-- text/xml format -->
<template-library error-template="">
<!--
In the first level the templates are declared.
When the template is requested and does not exist nothing is rendered.
If an error happens during that procedure the core uses the error-template.
When the 'binding' does not have any value the empty-template is used.
When the 'binding' needs to do a resource resolve ($.get / $.ajax)
the loading-template is used to show possible delay.
-->
<tree-view>
<tree-node empty-template="no-tree-nodes" />
</tree-view>
<tree-node empty-template="" loading-template="entity-link-loader">
<div>
<a href='#{{= $(this).attr("name") }}'>
<img src="{{= $(this).attr("imageUrl") }}" alt="{{= $(this).attr("name") }}" />
<span>{{= $(this).attr("name") }}</span>
</a>
<!--
The following shows includance in the specific point.
The query queries the $(this) of the data source (for example).
-->
<tree-node query="node" empty-template="no-field-entity-link" />
</div>
</tree-node>
<no-tree-nodes>
<!-- empty - nothing is rendered here -->
</no-tree-nodes>
<no-field-entity-link>
<div>There are no classes in this instance</div>
</no-field-entity-link>
<!--
Includance example
-->
<centered-element>
<div class="centered-somewhere">
<contents />
</div>
</centered-element>
<entity-link-loader>
<centered-element> <!-- you can use another template to produce wrapper -->
<img src="loading.gif" alt="Loading..." />
</centered-element>
</entity-link-loader>
<!-- hopefully some parts of library could be lazy-loaded from a server -->
<remote-enabled-field-entity-link url="http://tempuri.org/remoteLibrary.xml" loading-template="entity-link-loader" />
</template-library>
</script>
Thank you for reading!
Re: Re: jQuery Templates Proposal
11 years ago
Alexander: Your proposal definitely looks interesting but I tend to wonder how much file size people are expecting to increase jQuery by when the templating is added. I don't really think it's practical to have a full-featured XML-based templating system for the simple fact that it would increase the filesize of jQuery by about 5-10KB. With both the templating and script loading modules I don't want to increase the size of jQuery by any more than 1KB each.
That being said I do like the idea of wrapper templates being able to easily wrap their contents. I'll have to mull this over and see if there are some easy solutions for this.
That being said I do like the idea of wrapper templates being able to easily wrap their contents. I'll have to mull this over and see if there are some easy solutions for this.
Leave a comment on alexander.mantzoukas's reply
Re: jQuery Templates Proposal
11 years ago
Hello.
Want to propose an idea that I've already implemented in my framework for the template libraries. What about to hold all templates in a separate xml/text files, and do AJAX loading them? In <head> we can use tag <link> that will be working as a linkage to template library file or even files. And using "rel" attribute we may cast this <link> to work only for templates. Example:
<link href="assets/xml/tpl_core.xml" rel="jquery-template" type="text/xml" />
In such way page will pass W3C validation (btw, less code in HTML - better for SEO), and allows to developers to manage template libraries on a fly ;)
Want to propose an idea that I've already implemented in my framework for the template libraries. What about to hold all templates in a separate xml/text files, and do AJAX loading them? In <head> we can use tag <link> that will be working as a linkage to template library file or even files. And using "rel" attribute we may cast this <link> to work only for templates. Example:
<link href="assets/xml/tpl_core.xml" rel="jquery-template" type="text/xml" />
In such way page will pass W3C validation (btw, less code in HTML - better for SEO), and allows to developers to manage template libraries on a fly ;)
Re: Re: jQuery Templates Proposal
11 years ago
As a solution to this I was actually thinking of just improving on the existing .load method, like so:
Naturally the browser would take care of all the caching for us on future requests so we'd only have that initial on-demand request.
- $("#test").load("some.tmpl", { user: "John" });
Naturally the browser would take care of all the caching for us on future requests so we'd only have that initial on-demand request.
Re: Re: jQuery Templates Proposal
11 years ago
Sure, new improved .load method is a good way, but it requires to initiate it only manually.
With developing thousands of sites I've came to a huge list of requirements that allows spend less time on developing and re-developing of already existing sites. So just wanted to share with idea that does life easier to both sides (programmers and designers). Short list looks so:
1. Any site has a bunch of templates that are used to every page. Much easier to separate them to one or couple files that will be loaded on a default and most important - already processed to DOM. Once loaded and processed, they are waiting to insertion or other manipulations.
2. Ability to change templates without touching HTML/JS codes. Allows to version templates and cast loading of certain bunch version in one demand. (No need to browse files to find the linkage to certain template file or template code and change it).
3. AJAX template loading on a demand.
In deed, based on huge practice, before assigning variables to template, it is better already to have it in library and processed as much as possible to DOM. In such way, we are getting better performance for future usage. Also, if we have the requirement to assign certain variables to template while processing it to DOM, we just need to post proceed the template with needed variables. And the other option is to passing variables on a demand while manipulating with existing DOM template.
With developing thousands of sites I've came to a huge list of requirements that allows spend less time on developing and re-developing of already existing sites. So just wanted to share with idea that does life easier to both sides (programmers and designers). Short list looks so:
1. Any site has a bunch of templates that are used to every page. Much easier to separate them to one or couple files that will be loaded on a default and most important - already processed to DOM. Once loaded and processed, they are waiting to insertion or other manipulations.
2. Ability to change templates without touching HTML/JS codes. Allows to version templates and cast loading of certain bunch version in one demand. (No need to browse files to find the linkage to certain template file or template code and change it).
3. AJAX template loading on a demand.
In deed, based on huge practice, before assigning variables to template, it is better already to have it in library and processed as much as possible to DOM. In such way, we are getting better performance for future usage. Also, if we have the requirement to assign certain variables to template while processing it to DOM, we just need to post proceed the template with needed variables. And the other option is to passing variables on a demand while manipulating with existing DOM template.
Re: Re: jQuery Templates Proposal
11 years ago
If you wish to pre-load and cache all your templates you can do that now with my proposed solution, you would just do:
And then you could just use it like so:
Only one script load and all the templates are pre-computed and cached.
- jQuery.extend(jQuery.templates, {
tmplA: jQuery.tmpl("...."),
tmplB: jQuery.tmpl("...."),
....
});
And then you could just use it like so:
- $("#foo").append("tmplA", { some data });
Only one script load and all the templates are pre-computed and cached.
Re: Re: jQuery Templates Proposal
11 years ago
From tech side you are doing very well.
Seems my comment consider <link> tag usage for templates should go to UI threads, as it was more connected as to make life easier to developers.
Seems my comment consider <link> tag usage for templates should go to UI threads, as it was more connected as to make life easier to developers.
Leave a comment on jaguar4adc's reply
Re: jQuery Templates Proposal
11 years ago
Wow, thank you everyone -- there's some really great feedback and thoughts in this thread!
We forked the prototype from John here:
http://github.com/nje/jquery-tmpl
And iterated on it with some ideas based on the feedback in this thread. We also updated our proposal on the wiki here:
http://wiki.github.com/nje/jquery/jquery-templates-proposal#jquerycore
One thing said multiple times in this thread is concern over the templates becoming too complex. In this update we propose ideas that allow you to keep templates simple, but without departing from using javascript as the expression language. In fact, with these ideas, it is completely possible to have no expressions in the template at all, or to have only very simple ones, no matter how complex your scenario might be.
There are three main things that complicate templates:
1. Embedding calculated values or expressions, such as formatting a number as currency, or a date in a readable form, handling nulls, etc.
2. Iterating over nested data.
3. Conditional logic
The updated proposal shows how you can use two callbacks to deal with these issues in a way that keeps the code in your javascript and out of your template, even if you have nested data to display. Please do look at the proposal or jump straight to the git fork -- it also has an updated demo.html. The proposal itself goes into more details and examples.
Leave a comment on infinity88's reply
Re: jQuery Templates Proposal
11 years ago
Hi infinity88,
I am attaching a small parser function that I have created according to previous specs. I have seen the comment on lines 144-147. The regexes are using {{ ... }} notation.
I know it is ugly but I hope that it give you guys some boost (or just testing) for the community demo.
-- Alex
I am attaching a small parser function that I have created according to previous specs. I have seen the comment on lines 144-147. The regexes are using {{ ... }} notation.
I know it is ugly but I hope that it give you guys some boost (or just testing) for the community demo.
-- Alex
- function evaluateTemplate(templateName)
{
var html = $("script#" + templateName + "[type='text/x-jquery-template']").html();
if (!html || typeof(html) != "string" || html.match(/^\s*$/))
return "";
// Change string and return by executing the resulting html string
html = html.replace(/[\n\r\t\s]+/g, " ");
htmlParts = html.split("{{");
for(var n = 0; n < htmlParts.length; ++n)
{
if (htmlParts[n].indexOf("}}") > -1)
{
var subParts = htmlParts[n].split("}}");
subParts[1] = subParts[1].replace(/"/g, "\\\"");
htmlParts[n] = subParts.join("}}");
}
else htmlParts[n] = htmlParts[n].replace(/"/g, "\\\"");
}
html = htmlParts.join("{{");
// Replace the information with evaluation
// After binding {{:after ... }} [code that runs after binding]
var afterMethod = html.match(/\{\{\:after(.+?)\}\}/g);
if (afterMethod)
{
afterMethod = eval("(function __stub() { return function() { " + afterMethod[0].replace(/\{\{\:after(.+?)\}\}/g, "$1") + "} })();");
html = html.replace(/\{\{\:after(.+?)\}\}/g, "");
}
// Entries {{@ ... }} [template content entry point]
// html = html.replace(/\{\{@(.+?)\}\}/g, "\" + $1 + \"");
// String evaluation {{= ... }} [append to output]
html = html.replace(/\{\{=(.+?)\}\}/g, "\" + $1 + \"");
// Logic evaluation {{ ... }} [run accross output]
html = html.replace(/\{\{(.+?)\}\}/g, "\"; $1 \"");
html = "\"" + html + "\"";
html = eval(html);
return { "html" : html, "after" : afterMethod };
}
Leave a comment on alexander.mantzoukas's reply
Re: jQuery Templates Proposal
11 years ago
Using nested tags inside <script type="text/x-jquery-template"> and <style> is not W3C valid. Perhaps, better to avoid this.
Re: Re: jQuery Templates Proposal
11 years ago
To whom are you replying? I don't think anyone was suggesting having script elements inside script elements (or style inside style, for that matter).
Re: Re: jQuery Templates Proposal
11 years ago
My bad. It was addressed to alexander.mantzoukas. Also, it is still exists in proposal from infinity88 :
http://wiki.github.com/nje/jquery/jquery-templates-proposal#jquerycore
http://wiki.github.com/nje/jquery/jquery-templates-proposal#jquerycore
Re: Re: jQuery Templates Proposal
11 years ago
Example from proposal:
<script id="template" type="text/html">That is not passing w3c validation ...
<li>{%= name %} - {%= price %}</li>
</script>
Re: Re: jQuery Templates Proposal
11 years ago
How so? Works great for me:
http://gyazo.com/85f6703213f31d14e2b21f1f8ef18746.png
(The warnings are related to HTML 5 and the encoding of the page.)
http://gyazo.com/85f6703213f31d14e2b21f1f8ef18746.png
(The warnings are related to HTML 5 and the encoding of the page.)
Re: Re: jQuery Templates Proposal
11 years ago
From HTML5 (experimental) - it looks fine. But from side of most spread XHTML 1.0 Transitional - getting errors.
What about to not connect with <script> tag at all, and assign class to any tag that holds template?
What about to not connect with <script> tag at all, and assign class to any tag that holds template?
Re: Re: jQuery Templates Proposal
11 years ago
For example <iframe>:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>Test</title></head>
<body>
<iframe id="template_pattern" class="template" title="Some Template Information">
<ul>
<li>{%= name %} - {%= price %}</li>
</ul>
</iframe>
</body>
</html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>Test</title></head>
<body>
<iframe id="template_pattern" class="template" title="Some Template Information">
<ul>
<li>{%= name %} - {%= price %}</li>
</ul>
</iframe>
</body>
</html>
Leave a comment on jaguar4adc's reply
Re: jQuery Templates Proposal
11 years ago
Really, why it is needed to complicate things and use text templating code inside HTML? Just have templates library that is is already DOM and if you need to add more templates or re-construct existing ones, just use DOM manipulation.
And for initial template library setup - use it from external file, and if it is very needed to pass the template like inline HTML code, just pass it as a plain text by javascript.
And for initial template library setup - use it from external file, and if it is very needed to pass the template like inline HTML code, just pass it as a plain text by javascript.
Re: Re: jQuery Templates Proposal
11 years ago
Why? Because complex structures are challenging to build - and even with a simplified DOM API it can still be challenging - not to mention computationally expensive.
Re: Re: jQuery Templates Proposal
11 years ago
Agree. My template framework based on another requirements. So inline template code will be very useful. Btw, in thread was mentioned link to "Haml" for Ruby. Something similar I was already using for templates in javascript. Will be good to implement similar DOM constructor too, especially closely connected with templates.
Leave a comment on jaguar4adc's reply
Re: jQuery Templates Proposal
11 years ago
Perhaps this has already been covered- the {% syntax clashes with a few other templating engines out there. Could the delimiters be configurable so the library could sit nicely alongside whichever server-side templating engine happens to be in use, without resorting to escaping (which may not even be available - I can't see how to do it in tornado for example.)
Re: Re: jQuery Templates Proposal
11 years ago
Thanks for the heads up! Making the delimiters configurable is an interesting idea, but one thing about that is it means plugins that come with their own templates couldn’t rely on it since they don’t know the delimiter at development time. To work with a configured app using their plugin, they’d have to use the delimiter dynamically, which wouldn’t be very clean, and they’d also have to worry about escaping anything in the template that collides with the configured delimiter.
What about {$ $} and {$= $} instead? The dollar sign kind of goes along with jQuery.
Re: Re: jQuery Templates Proposal
11 years ago
Just to follow the needed thread, posting link again:
http://smarty.incutio.com/?page=SmartyFrequentlyAskedQuestions#template-1
That was example like very popular server side PHP templates engine - Smarty incorporated in.
http://smarty.incutio.com/?page=SmartyFrequentlyAskedQuestions#template-1
That was example like very popular server side PHP templates engine - Smarty incorporated in.
Re: Re: jQuery Templates Proposal
11 years ago
On reflection, I think configurable delimiters are perfectly viable:
- render() could have an optional argument listing delimiters
- internally, the regexes for template processing would be cached by delimiter combination
Then, if there were a global option, plugin authors could protect their code by always referencing their own delimiters.
Alternatively, there is no global option and the only people who pass alternative delimiters are those who are defining their own. If the syntactic overhead seems too great, it would be easy for those people to make an ad-hoc plugin, fn.myRender(), which curries the delimiter settings into the call.
Another tantalizing possibility of this approach is that it would become relatively easy to match jQuery's template style to your chosen framework and, for simple use cases, use the same templates server- and client-side.
- render() could have an optional argument listing delimiters
- internally, the regexes for template processing would be cached by delimiter combination
Then, if there were a global option, plugin authors could protect their code by always referencing their own delimiters.
Alternatively, there is no global option and the only people who pass alternative delimiters are those who are defining their own. If the syntactic overhead seems too great, it would be easy for those people to make an ad-hoc plugin, fn.myRender(), which curries the delimiter settings into the call.
Another tantalizing possibility of this approach is that it would become relatively easy to match jQuery's template style to your chosen framework and, for simple use cases, use the same templates server- and client-side.
Leave a comment on drgordon's reply
Re: jQuery Templates Proposal
11 years ago
might get confusing....What about {$ $} and {$= $} instead? The dollar sign kind of goes along with jQuery.
- {$$("#myDiv").each(...$}
i like {% more
Leave a comment on leeoniya's reply
Re: jQuery Templates Proposal
11 years ago
As for cross platformed delimiters, it is just needed to exclude most regular symbols combinations that are used in most popular server side programming languages and server side templating systems. Here is the list to start up:
1. PHP:
exclude:
1.1. Smarty, Dwoo, Template Ligh, Rain TPL, vlibTemplate, Worx:
2. ASP:
2.1. Spark, Sharp Tiles, Brail:
3. ColdFussion:
templates:
4.1. Django, Jinja2:
5. Velocity:
============= CANDIDATES ==============
Single symbol:
Combination of 2:
Combination of 3:
Combination of 4:
Example:
--->>> Edition #5
If somebody knows more delimiters to exclude, go ahead and add them to those list.
To my mind better to use default delimiters like Smart has in PHP, and allow the option to setup custom delimiters (btw, like Smarty can do: http://smarty.incutio.com/?page=SmartyFrequentlyAskedQuestions#template-1 )
1. PHP:
exclude:
a) <? ?>
b) <?= ?>
c) $
d) /* */
e) ->
templates:b) <?= ?>
c) $
d) /* */
e) ->
1.1. Smarty, Dwoo, Template Ligh, Rain TPL, vlibTemplate, Worx:
a) { } {/ }
b) {* *}
1.2. Savant 3:b) {* *}
a) <? ?>
1.3. Twig:a) {% %}
b) {{ }}
c) {# #}
b) {{ }}
c) {# #}
2. ASP:
a) <% %> with variations of <%# and <%@ and <%=
b) ///
c) @" ";
templates:b) ///
c) @" ";
2.1. Spark, Sharp Tiles, Brail:
a) ${ }
b) !{ }
c) ${# }
d) #
2.2. String Template:b) !{ }
c) ${# }
d) #
a) $ $
b) $ :{ }$
b) $ :{ }$
3. ColdFussion:
a) <cfoutput></cfoutput> includes all tags that it is operating with
b) <!--- --->
4. Python:b) <!--- --->
templates:
4.1. Django, Jinja2:
a) {% %}
b) {{ }}
c) {# #}
4.2. Cheetah:b) {{ }}
c) {# #}
a) #
b) $
b) $
a) #
b) $
b) $
============= CANDIDATES ==============
Single symbol:
1) |
Combination of 2:
1. a) |= |
Combination of 3:
1. a) |*= *|
1. b) |%= %|
1. c) |@= @|
1. d) |"= "|
1. e) |&= &|
1. b) |%= %|
1. c) |@= @|
1. d) |"= "|
1. e) |&= &|
Combination of 4:
1. a) |*= *|
1. b) |*%= %*|
1. c) |*@= @*|
1. d) |*"= "*|
1. e) |*&= &*|
1. b) |*%= %*|
1. c) |*@= @*|
1. d) |*"= "*|
1. e) |*&= &*|
Example:
<div id="template_pattern" class="template">
<ul>
<li>|%= name %| - |%= price %|</li>
</ul>
</div>
--->>> Edition #5
If somebody knows more delimiters to exclude, go ahead and add them to those list.
To my mind better to use default delimiters like Smart has in PHP, and allow the option to setup custom delimiters (btw, like Smarty can do: http://smarty.incutio.com/?page=SmartyFrequentlyAskedQuestions#template-1 )
Re: Re: jQuery Templates Proposal
11 years ago
As as been mentioned, Django, Jinja2, Twig all use {{ and {%.
I'm sure that a bunch of people are going to have to escape a whole bunch of strings no matter what gets picked. The very least we can do is try to avoid colliding with the bigger programing languages (PHP/ASP/JSP). I'm for Django style.
Re: Re: jQuery Templates Proposal
11 years ago
Common people! Make some activity! I am sure that everybody tired from this thread. So let's finish with this once and forever.
Can say to all, if you won't help with delimiters that you want to exclude, it can be late ;)
Updating my message with edition #4 with first candidate symbol |
Can say to all, if you won't help with delimiters that you want to exclude, it can be late ;)
Updating my message with edition #4 with first candidate symbol |
Leave a comment on jaguar4adc's reply
Re: jQuery Templates Proposal
11 years ago
Updated the list of delimiters up to edition #5.
Example:
For commenting I propose to use *
or plain text comments:
Example:
<div id="template_pattern" class="template">
<ul>
<li>|%= name %| - |%= price %|</li>
</ul>
</div>
For commenting I propose to use *
<li>|*%= name %*| - |*%= price %*|</li>
or plain text comments:
<div>|* some comments goes here *|</div>
Leave a comment on jaguar4adc's reply
Re: jQuery Templates Proposal
11 years ago
I've been working on my own templating library for a little while, and after some serious thinking, I came to a few conclusions:
0. The actual delemiters chosen are not important {% %} <! > {{}}, {##}, are all more or less the same
1. The templating syntax must allow full JS expressions... not just a dumbed down syntax (like jinja or django, etc). The same way that PHP templates allow full PHP usage.
2. Many frameworks have the basic idea covered... load/cache/compile a template, feed it a literal object and provide callbacks.
3. While I like the Idea of Johns MicroTemplating, this ideal templating engine must be possible without using the evil eval function or the Function() constructor. Using any of these would make the use of jQuery core a liability to too many newbies that are pluging jQuery everywhere on the net.
These conclusions made me understand that the "weakest" link would be how the templating engine would evaluate expression... this is why I started building a flexible expression engine, which later became a Javascript meta-interpreter.
I call it JaJa and the project is available at : http://jaja.masyl.net
The project is already at a state where it could provide decent expressions evaluation to a templating library, but while working on JaJa I quickly realized that building a fast and safe templating engine would be very easy once Javascript compilation would be possible.
So... the same way JaJa can parse Javascript, later on It will receive a few additional parsing handlers and "voilà!"... it will be able to compile mixed html and JS, just like PHP. Wrap this in a jQuery plugin and you have a solution.
I expect to keep working hardon JaJa for the next tree months and end-up with some solid code.
Feel free to fork/join my little project or go look at it for inspiration.
Re: Re: jQuery Templates Proposal
11 years ago
While I think what you are doing is awesome, I think a full blown JavaScript implementation within jQuery is way too much code for a built-in jQuery templating system.
You can do pretty much everything the current Django template system can do in terms of code evaluation with a basic implementations of Shunting yard and Postfix evaluation. And keep all the operators pluggable.
Note that Eval/Function are already used by jQuery to evaluate JSON.
Leave a comment on mathieusylvain's reply
Re: jQuery Templates Proposal
11 years ago
I may be a bit of a neurotic neat freak, but putting logic in templates drives me bananas.
There's no solution involving any variant of <%= %> that will fix the fundamental problem with templates, which is that logic and markup turn into soup when combined at room temperature. Fortunately, someone thought of a way to fix it: Mustache. http://github.com/defunkt/mustache
There's even a handy dandy ready-to-go port of it to JS: http://github.com/janl/mustache.js
Take it for a test drive, it will bring joy to your life.
Re: Re: jQuery Templates Proposal
11 years ago
Just as a user of jQuery, I'd love for mustache.js to be the default templating library.
+1 mustache.js
Leave a comment on micah.snyder's reply
Re: jQuery Templates Proposal
11 years ago
One question: How do you debug the template?
This was the fundamental problem I had with the original Microtemplating code, Rick Strahl's version and the jqote plugin.
Re: Re: jQuery Templates Proposal
11 years ago
Heh. The parser throws exceptions when it encounters invalid syntax?
This is an issue with jQuery itself which doesn't exactly tell you the minute details of what went wrong with "variable m" in "line 1 of jquery.min.js". :-)
Leave a comment on austegard's reply
Re: jQuery Templates Proposal
11 years ago
If you like mustache.js, just upvote Micah's comment so we don't end up with a bunch of "me too" AOL-style comments.
Debugging a template can definitely be tricky. Are there any features a templating system could add that would help with the problem?
Debugging a template can definitely be tricky. Are there any features a templating system could add that would help with the problem?
Re: Re: jQuery Templates Proposal
11 years ago
In general, I think most templating systems would need to remove a feature to help debugging -- that feature being hybrid logic / template syntax.
The intermingling of expressions in different languages is parser (and hence debugger) un-friendly, which is why I favor the Mustache style of flat symbols that simply point to the expression you want to evaluate. In a Mustache template you can evaluate all of the actual logic as a plain javascript object, which to me is a huge benefit, as highlighted here by the debugging discussion.
And yeah, I fully realize that I have a horse in this race now, so my opinion isn't all that objective ;)
Leave a comment on dave.methvin's reply
Re: jQuery Templates Proposal
11 years ago
I don't think this belongs in jQuery. Even in JavaScriptMVC which supports the extremely powefull EJS templates, one of the most requested features is using other templating engines.
Like EJS, the templates should not be in the DOM. This is ugly. But, you should be able to package them into your build file (like JMVC does for EJS).
I still think these things should be united in a jQuery Enterprise project.
To answer one of John's questions ... Yes, partial templates is absolutely needed. With big projects, it's the only way to keep templates clean.
I
Leave a comment on justinbmeyer's reply
Re: jQuery Templates Proposal
11 years ago
I really like the idea of a standard jquery templating solution. Whether or not it is part of core is irrelevant to me, as long as there is a clear and obvious jquery standard so that plugin developers can leverage it.
However, I am also a purist and don't believe that any logic (even looping) belongs in the templates themselves. I moved away from all of the ASP/PHP/JSP solutions long ago because of this.
I see that the proposal has a section on "Expressionless Templates", which is a great start in this direction and I hope that it is retained. In a way, it is similar to the approach that the Wicket java framework takes in completely separating code from html. Wicket is brilliant in this regard and extremely powerful. Obviously, it can't directly be used, but I would highly recommend considering its design.
My thought is that the templating system would use convention over configuration with the ability to customize it when needed. As long as the hierarchy of HTML entity class names in the template match the data model's hierarchy, the data in the model would simply populate into the template. Any data that is an array would automatically repeat the matching HTML element in the template and its content.
A view could be applied if desired that would allow data from the model to be manipulated before being inserted as well as add the ability to add additional calculated values. The view would also permit logic and other structures to be utilized (such as including or not including certain data) without requiring anything in the template besides HTML with classnames or IDs.
Here's an example:
- <script type="text/javascript">
- $(function() {
- var template = "#template";
- var model = [
- { name: "Bob Smith", dob: "1976-10-1", phones: [
- {name:"Home",value:"555-1111"},
- {name:"Mobile",value:"555-2222"}
- ] },
- { name: "Sue Black", dob: "1984-6-23", phones: [
- {name:"Office",value:"555-3333"}
- ] }
- ];
- var view = {
- /* Only show users over 30 years old */
- over30: {
- _visible: function(context) {
- if (calcAge(context.dob) > 30) return true;
- return false;
- },
- /* Override dob with custom output */
- dob: function(context) {return prettyDob(context.dob);},
- /* Add additional calculated value */
- age: function(context) {return calcAge(context.dob);},
- phones: {
- /* Override phone number to include international prefix */
- value: function(context) {return formatPhone(context.value);}
- }
- }
- function calcAge(dob){ return ... };
- function prettyDob(dob){ return ... };
- function formatPhone(phone) { return "001-"+phone };
- $("ul").append(template, model, view);
- });
- </script>
This would be the HTML, which contains the template:
- <script id="template" type="text/html">
- <li class="over30">
- <div>
- <strong class="name"/>:
- Born on <span class="dob"/>
- (<span class="age"/> years old)
- </div>
- <ul class="phones">
- <li>
- <strong class="name"/>:
- <span class="value"/>
- </li>
- </ul>
- </li>
- </script>
- <ul></ul>
This output would be created:
- <ul>
- <li class="over30">
- <div>
- <strong class="name">Bob Smith</strong>:
- Born on <span class="dob">October 1, 1976</span>
- (<span class="age">33</span> years old)
- </div>
- <ul class="phones">
- <li>
- <strong class="name">Home</strong>:
- <span class="value">001-555-1111</span>
- </li>
- <li>
- <strong class="name">Mobile</strong>:
- <span class="value">001-555-2222</span>
- </li>
- </ul>
- </li>
- </ul>
Obviously, I haven't completely thought this through. It is just an initial rough stab. And maybe something like this has already been suggested or is used by another templating engine. But if something could be done along these lines, it seems like the templates could be reduced to nothing more than HTML. No need for {{ }} or anything.
Re: Re: jQuery Templates Proposal
11 years ago
Completely agree with convention over configuration.
And no, your rough jab is right on, pure templates already does this, and chain.js apparently too.
Currently i use jTemplates, which is pretty easy to use and understand, but it chops up the html too much for my taste. Pure templates seemed like godsend but just couldn't get the syntax in my head, so i tried to write up my own and ended up with chef.templates(). The principle is the same as pure templates, but the syntax is much closer to what i'm used with in jQuery. (still alpha stuff).
Html
<div id="#template">
<div class="name">this name was filled server-side</div>
</div>
jQuery
<script type="text/javascript">
// from user feedback, ajax/jsonp, etc ....
var data = [{name: "foo"}, {name: "bar"}];
$("#template").render(data, callback);
</script>
Result
<div id="#template">
<div class="name">foo</div>
<div class="name">bar</div>
</div>
I hope templates for jquery will go the html/css way instead of the programmers way. That said, jQuery totally rocks and is fun to play with !
-
Robert
And no, your rough jab is right on, pure templates already does this, and chain.js apparently too.
Currently i use jTemplates, which is pretty easy to use and understand, but it chops up the html too much for my taste. Pure templates seemed like godsend but just couldn't get the syntax in my head, so i tried to write up my own and ended up with chef.templates(). The principle is the same as pure templates, but the syntax is much closer to what i'm used with in jQuery. (still alpha stuff).
Html
<div id="#template">
<div class="name">this name was filled server-side</div>
</div>
jQuery
<script type="text/javascript">
// from user feedback, ajax/jsonp, etc ....
var data = [{name: "foo"}, {name: "bar"}];
$("#template").render(data, callback);
</script>
Result
<div id="#template">
<div class="name">foo</div>
<div class="name">bar</div>
</div>
I hope templates for jquery will go the html/css way instead of the programmers way. That said, jQuery totally rocks and is fun to play with !
-
Robert
Leave a comment on tauren's reply
Re: jQuery Templates Proposal
11 years ago
Justin, I'd like to have an "official" jQuery templating system just because it's such a useful feature; whether it's a team-supported plugin or something baked into core probably doesn't matter much. If it's not a lot of code, putting it in core would be handy. But of course that tends to drive a Spartan implementation versus the greater freedom of a plugin.
> Like EJS, the templates should not be in the DOM. This is ugly. But, you should be able to package them into your build file (like JMVC does for EJS).
EJS templates suffer from the problem Micah described, they end up mixing programming logic with the markup. Then we're back to the same mess we fled a few years ago with Classic ASP or PHP intermingling code and markup.
Sometimes it's handy to have the template in the document. I don't have a build file for many projects, it's just .html plus .js and doesn't need to be more complicated than that.
> Like EJS, the templates should not be in the DOM. This is ugly. But, you should be able to package them into your build file (like JMVC does for EJS).
EJS templates suffer from the problem Micah described, they end up mixing programming logic with the markup. Then we're back to the same mess we fled a few years ago with Classic ASP or PHP intermingling code and markup.
Sometimes it's handy to have the template in the document. I don't have a build file for many projects, it's just .html plus .js and doesn't need to be more complicated than that.
Re: Re: jQuery Templates Proposal
11 years ago
Dave,
Your criticism of EJS has been a common, but in my opinion, inaccurate critique of EJS. But before I explain, I think you just helped my "BIG" point ... that everyone has a favorite templating system with strong opinions, and that including one in jQuery doesn't make sense.
I've been using templates in some form for 3 years on about 10-12 projects. I've used John's Micro Templates, JAML, EJS, and TrimPath's templates. Despite all this, I've never found myself in a situation seeing classic ASP or PHPs problems. This includes using EJS on projects over 100k lines of code. This is because the client is fundamentally different than the server.
In PHP and ASP, you start and end with the page. It's only natural in this situation to start adding logic in the page to start seeing results. Using templates in JS is an entirely different situation. Your code starts with an event and ends with updating the DOM. This is why Ruby on Rails doesn't have as much of a problem with code in views - your code starts in Controllers.
Client side programming is very different than ASP and PHP development. And although templates like EJS still allow for 'bad' logic in the template, in my opinion, their power makes up for it. But, I'm not arguing for EJS in jQuery.
Next point ...
If you don't have a build for most projects, we work on entirely different types of projects. A build is unavoidable in the complex projects that I work on. But that's great that jQuery can provide a useful tool for a wide variety of developers. I want to ensure that continues.
If there is a jQuery template, it needs to scale to meet "enterprise" development challenges. You need to be able to not have it in the DOM. What if I want to release a plugin that uses a template? I need a way to include it and package it easy.
All of JMVC's supported views (JAML, Micro, EJS) support the holy trinity:
- Can load in a script tag in the document
- Can load from an external file
- Can be processed, compressed, and package along with another plugin
Anything jQuery provides should do likewise.
Re: Re: jQuery Templates Proposal
11 years ago
Justin,
I agree with your scaling concerns. I think the best approach to accommodating a wide range of use cases (in this case) is to implement a templating system that's as simple and agnostic as possible.
And really, that basic infrastructure (storing / fetching / including templates) can and should be decoupled for the actual template parser. Even $.fn.render can just run whatever templating engine has been dropped in. jQuery templates would, if I ran the zoo, be managed by jQuery completely separate from the engine that renders them.
So I guess the discussion here has two separate-but-related discussions going on about syntax and architecture.
Leave a comment on dave.methvin's reply
Re: jQuery Templates Proposal
11 years ago
One of the features of jTemplates you bullet in your proposal is "live updating". I've been using jqote and find it a little annoying to have to use .append() to put the template output into the DOM, if I'm later going to have to update it. I end up having to do $("#parentelement").empty() followed by a new call to jqote to get new data and re-append the output to #parentelement. .
Am I correct in understanding that where the section "jQuery DOM Manipulation" uses only the example of .append(), that it's really referring to new functionality for all DOM manipulation functions like appendTo, prepend, .remove, etc.?
Leave a comment on heyotwell's reply
Proposal - Template IL language
11 years ago
Was thinking that supporting multiple templating languages would be an advantage and got to thinking about a templating IL (intermediate language). Html represented by nested Key/value pairs with values as literals or functions. jQuery itself only uses IL, higher level languages to be supported by further plug-ins which "compile" to this IL eg:
- //A sample of template IL (json) that could be created from a higher scripting language
- //IL keys are evaluated to either tag or attribute and written to buffer
- //Data is always passed as first parameter to any functions in the template
- //"this" evaluates to the template buffer
- var il = {
- table: [{style: 'solid 1px'}, {
- thead: [{
- th: 'Column 1',
- th: 'Column 2'
- }],
- tbody: function(data) {
- //Nested template here
- var il2 = {
- tr: [{
- td: function(row) {
- this.write(row.Id);
- },
- td: function(row) {
- this.write(row.Name);
- }
- }]
- }
- //Combine template with data for each row
- for (var i=0; i<data.rows.length;i++)
- {
- this.write($.templ(il2, data));
- }
- }
- }]
- };
- //Replace contents of div with combination of template IL and data
- //Note can use existing manipulation functions such as prepend etc
- $(div).html($.templ(il, data));
Leave a comment on james.westgate's reply
Re: jQuery Templates Proposal
11 years ago
The template system in PrototypeJS is very simple but extend-able.
It simply uses a #{symbol} syntax for the actual replacement, but allows you to define an optional regex that will match any pattern you want.
I think the data binding should be separate from the templating. Creating a simpler template function leads to using "ViewModels" for the actual data binding. You gather in your data objects from various sources, create a specific model object for the template and then evaluate the template using that model. Which I think will prevent the mixing together of logic with presentation and will still allow various validation/formatting plugins to work on the ViewModel.
Re: Re: jQuery Templates Proposal
11 years ago
Mustache does what you're looking for in a framework-agnostic way. See my post up a ways
Leave a comment on scottkoon's reply
Re: jQuery Templates Proposal
11 years ago
Unfortunately I don't have the time to read through all the posts, but I've skimmed it and there seem to be no mention of the idea I'm proposing.
About a year ago I was faced with a pretty big JavaScript driven application that required heavy usage of templates. I've tried out all of the template engines mentioned in the proposal and found non to be exactly what I needed. I ended up writing my own engine based on John's idea. Unfortunately my engine can't be implemented as a jQuery plugin since I wrote a simple compiler that compiles templates into JavaScript code during deployment of the application.
In a large JavaScript application that uses tens or hundreds of templates inserting templates into script or style tags is not the way to go. I would suggest implementing a way to load multiple templates using one http request. If I remember correctly jTemplates supports multiple templates in a single file, and from my experience, it is a must have in bigger projects.
About a year ago I was faced with a pretty big JavaScript driven application that required heavy usage of templates. I've tried out all of the template engines mentioned in the proposal and found non to be exactly what I needed. I ended up writing my own engine based on John's idea. Unfortunately my engine can't be implemented as a jQuery plugin since I wrote a simple compiler that compiles templates into JavaScript code during deployment of the application.
In a large JavaScript application that uses tens or hundreds of templates inserting templates into script or style tags is not the way to go. I would suggest implementing a way to load multiple templates using one http request. If I remember correctly jTemplates supports multiple templates in a single file, and from my experience, it is a must have in bigger projects.
Leave a comment on grga.curkovic's reply
Re: jQuery Templates Proposal
11 years ago
Hello,
I'm quite a newbie with jquery, but I wanted to share my thoughts anyway. Take them with a grain of salt.
I've matured some experience with john's microtemplating: i've ported the tpl->js function to PHP, and I transparently compile the templates server-side on demand, with caching. If the template file is altered, the the corresponding js is regenerated upon the next request. I've also extended the syntax to allow multiple templates inside a single js, and to execute the equivalent of the "rendering()" and "rendered()" methods.
The problems I'm encountering:
1) It's easy to put non-trivial logic inside the template, and debugging becomes a real nightmare.
2) The extra scope introduced by all those with constructs blocks minification/obfuscation.
3) The syntax with <% %> causes havoc in text editors / IDE.
So, my own opinions, based on this experience:
It's much better to restrict the code allowed inside the template to a single expression (a function call, traversing an object to get a property). No multi statement blocks, assignments, other constructs.
The template engine should provide it's own mechanism to iterate an array/object and to conditionally include a subpart. Like using "each"..."end" and "if"..."end". Using jquery's each() iterator (like john suggested) poses the problem of mapping "this" and "index" inside the block (which could contain nested "each"..."end" blocks).
An option to prevent the "with" construct usage would be nice. I'm perfectly fine with typing "$tpl.item" instead of "item", and retain code minification / obfuscation. Maybe $context.data.item is a bit too long.
Also, +1 to the django-like syntax.
Mustache is nice, but I don't like the mixing of the data together with the logic used to format/display it, inside the same object. I think the logic belongs to the template, not the data. Also, I find the usage of {{.}} a bit limiting... for ex, what if I want to enumerate object properties, with key and value?
I'm quite a newbie with jquery, but I wanted to share my thoughts anyway. Take them with a grain of salt.
I've matured some experience with john's microtemplating: i've ported the tpl->js function to PHP, and I transparently compile the templates server-side on demand, with caching. If the template file is altered, the the corresponding js is regenerated upon the next request. I've also extended the syntax to allow multiple templates inside a single js, and to execute the equivalent of the "rendering()" and "rendered()" methods.
The problems I'm encountering:
1) It's easy to put non-trivial logic inside the template, and debugging becomes a real nightmare.
2) The extra scope introduced by all those with constructs blocks minification/obfuscation.
3) The syntax with <% %> causes havoc in text editors / IDE.
So, my own opinions, based on this experience:
It's much better to restrict the code allowed inside the template to a single expression (a function call, traversing an object to get a property). No multi statement blocks, assignments, other constructs.
The template engine should provide it's own mechanism to iterate an array/object and to conditionally include a subpart. Like using "each"..."end" and "if"..."end". Using jquery's each() iterator (like john suggested) poses the problem of mapping "this" and "index" inside the block (which could contain nested "each"..."end" blocks).
An option to prevent the "with" construct usage would be nice. I'm perfectly fine with typing "$tpl.item" instead of "item", and retain code minification / obfuscation. Maybe $context.data.item is a bit too long.
Also, +1 to the django-like syntax.
Mustache is nice, but I don't like the mixing of the data together with the logic used to format/display it, inside the same object. I think the logic belongs to the template, not the data. Also, I find the usage of {{.}} a bit limiting... for ex, what if I want to enumerate object properties, with key and value?
Leave a comment on stephen.cantini's reply
Re: jQuery Templates Proposal
11 years ago
@Stephen
" ...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..."
Mybe we use different terminology? I am confused with this reasoning/motivation ? Does this motivation, has something to do with the MVC mantra where View directly uses Model ? Or is this aimed at using jQuery enabled pages in the MVVM pattern implementation?
jQuery is (among other things) an AJAX library. It lives and works under web applications, inside HTML pages running inside browsers. This kind of software delivery is usually called: RIA, short for "Rich Internet Application". Based on well known and established architectures and solutions: REST, JSON, AJAX, HTML5 etc...
I just can't seem to be able to "slot in" the "motivation paragraph" for this templates proposal, into any front end part of the RIA architecture?
Architecture of the RIA APP , has no "database" or "records" anywhere near the client side (aka browser+AJAX). Databases are "somewhere" in the Cloud. Or not. Data is coming out, and going in in a multitude of JSON supported ways. Simple.
Ideally RIA is an AJAX+JSON solution inside a browser. With "data" coming in from REST end-points, dotted all over the Cloud. What is behind a REST point AJAX client neither knows or cares about. IS it a document mgmt system, CouchDB or some SQL RDBMS, is completely irrelevant. Therefore there are no "records" or "datasets" ,and yes there is less and less xml, and certainly no "records" or "SQL cursors". Just JSON, HTML encoded traffic.
Also, if you are thinking in terms of "databases" and "records", allow me to predict that you must be thinking of some "appropriate" mechanism of getting to those "records", yes? Which, if I might guess further, must be some form of "querying"? This also confuses me Stephen?
People in 2010 (hopefully) do not "query the database" from the JavaScript running in the browser. There is no "SQL in the JavaScript" any more. Industry has understood why is this horrible, decades ago. For client side in general and for AJAX client in particular.
This is one of the main and key winning points for REST : no querying. Just urls. (with parameters) This is why nobody who was once burnt, does not do SOAP and WebServices anymore. AJAX+JSON+REST have won. There are no "databases" or "records" any more on the RIA browser side.
IE "XML Data Islands" , IE "DSO" objects and their "namedRecordset" property are long forgoten legacy. For a good reason. I am sure we all know exactly why.
For me JavaScript + templates = general confusion. But some people think it is "absoultely necessary", and who am I to tell them otherwise. Let them implement any plugin they see fit. What confuses me even more is why would anyone want to have "templating" *inside* jQuery? Why are we even discussing templates in the jQuery core forum ? Maybe I have missed something important which might easily prove me wrong ?
--DBJ
" ...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..."
Mybe we use different terminology? I am confused with this reasoning/motivation ? Does this motivation, has something to do with the MVC mantra where View directly uses Model ? Or is this aimed at using jQuery enabled pages in the MVVM pattern implementation?
jQuery is (among other things) an AJAX library. It lives and works under web applications, inside HTML pages running inside browsers. This kind of software delivery is usually called: RIA, short for "Rich Internet Application". Based on well known and established architectures and solutions: REST, JSON, AJAX, HTML5 etc...
I just can't seem to be able to "slot in" the "motivation paragraph" for this templates proposal, into any front end part of the RIA architecture?
Architecture of the RIA APP , has no "database" or "records" anywhere near the client side (aka browser+AJAX). Databases are "somewhere" in the Cloud. Or not. Data is coming out, and going in in a multitude of JSON supported ways. Simple.
Ideally RIA is an AJAX+JSON solution inside a browser. With "data" coming in from REST end-points, dotted all over the Cloud. What is behind a REST point AJAX client neither knows or cares about. IS it a document mgmt system, CouchDB or some SQL RDBMS, is completely irrelevant. Therefore there are no "records" or "datasets" ,and yes there is less and less xml, and certainly no "records" or "SQL cursors". Just JSON, HTML encoded traffic.
Also, if you are thinking in terms of "databases" and "records", allow me to predict that you must be thinking of some "appropriate" mechanism of getting to those "records", yes? Which, if I might guess further, must be some form of "querying"? This also confuses me Stephen?
People in 2010 (hopefully) do not "query the database" from the JavaScript running in the browser. There is no "SQL in the JavaScript" any more. Industry has understood why is this horrible, decades ago. For client side in general and for AJAX client in particular.
This is one of the main and key winning points for REST : no querying. Just urls. (with parameters) This is why nobody who was once burnt, does not do SOAP and WebServices anymore. AJAX+JSON+REST have won. There are no "databases" or "records" any more on the RIA browser side.
IE "XML Data Islands" , IE "DSO" objects and their "namedRecordset" property are long forgoten legacy. For a good reason. I am sure we all know exactly why.
For me JavaScript + templates = general confusion. But some people think it is "absoultely necessary", and who am I to tell them otherwise. Let them implement any plugin they see fit. What confuses me even more is why would anyone want to have "templating" *inside* jQuery? Why are we even discussing templates in the jQuery core forum ? Maybe I have missed something important which might easily prove me wrong ?
--DBJ
Re: Re: jQuery Templates Proposal
11 years ago
now, how did you do the connection between querying and templateing?
Re: Re: jQuery Templates Proposal
11 years ago
Yes, that's a terminology issue. The data Stephen is talking about is in JavaScript form when it reaches the template code. It may or may not come from a database, it doesn't matter. In the end, you have data in the form of a JavaScript object or array, and you inject that into a template. Nothing less, nothing more to read in the proposal.
Leave a comment on dbjdbj's reply
Re: jQuery Templates Proposal
11 years ago
i'd have to agree that templating doesn't belong in the core. a mustache plugin does the job just fine. maybe a "Recommended Plugins for Specific Tasks" list would be more appropriate and can be based on voting and discussion like we're doing here.
Re: Re: jQuery Templates Proposal
11 years ago
BLR said :
--DBJ
"...In the end, you have data in the form of a JavaScript object or array, and you inject that into a template. Nothing less, nothing more to read in the proposal..."
We are ok then, I guess? We are talking/thinking "just" on the subject of transforming JSON to HTML. The mechanism for doing it, that people call "templates".
Something that clearly does not belong into jQuery. Just a plugin.
Job done.
--DBJ
Leave a comment on leeoniya's reply
Re: jQuery Templates Proposal
11 years ago
It seems many people don't believe this belongs in core, and as I've said before, it doesn't really matter if it is in core or a separate official plugin. But I do think that if it does become a plugin, that it is fully documented and recommended on the jquery site as the official templating solution.
Many plugins could take advantage of a templating solution. I often use multiple plugins in my projects. If each plugin implements it's own templating solution, or picks different existing solutions, then I'm pulling in a lot more code to meet the same needs. If there is an official standard, then most plugins that need this feature would utilize the standard. If I also need a templating engine for my application, then the same engine is shared and the download overhead is reduced.
Are there any objections to having an official templating solution, or are the objections just about putting it in core?
Re: Re: jQuery Templates Proposal
11 years ago
"... it doesn't really matter if it is in core or a separate official plugin..."
Oh yes, it does matter. A lot.
+1 vote for developing "templates" as (official ;o) jQuery plugin.
(that means: no "templates" inside jQuery.*.js file)
--DBJ
--DBJ
Leave a comment on tauren's reply
Re: jQuery Templates Proposal
11 years ago
Where do we vote?
+1 for putting it in core (but not until mature/stable)
+1 for not permitting any logic at all in the templates...
We should build the template first, then insert the data second. If you have a lot of logic to work through then I expect you'll be looping over your data a lot and merging numerous smaller templates/fragments together. So we probably want an api which caters to those two activities: looping over json data and combining template fragments.
Leave a comment on fervr_john's reply
Re: jQuery Templates Proposal
11 years ago
Hello John, Stephen and all you guys.
I love this idea of the templating and I want to share with you my idea about it.
First of all a conceptual note. A truly jQuery template should (could) reflect the jQuery architecture. Now, one of the big challenges here is how do we embed code into the template itself as - obviously - we need to be able to control the flow of the result. The most obvious is the need of the "each" to iterate through an array etc.
I find John's suggestion interesting and inspiring at the same time:
- {each athlete_list}
- <li>{{ this.name|capFirst }}</li>
- {end}
I looked around at some other solution such as sparkviewengine and i came up with the following idea.
Does it make any sense to build up a template engine as a "declarative" way of writing jQuery?
Let my just try to sketch out few examples. By any means the different kind of syntax I use reflect possible solutions: they are not consistent but different suggestions.
- <li $:each="athlete_list">
- <$:text value="this.name" />
- </li>
The idea here is to use a sort of namespace "$:" to represent a jQuery function. It could be as well something like:
- <li jQuery:each="athlete_list">
- <jQuery:text value="this.name" />
- </li>
or
- <jQuery:each>
- some stuff...
- </jQuery:each>
Here we use the {$.<jquery function>} syntax
- {$.each athlete_list}
- <li>{$.value this.name}</li>
- {/$.each}
This is using the $(...).text(value) function
- <$:each value="athlete_list">
- <li>
- <a href="$:text(this.url)">
- <$:text value="this.name"/>
- </a>
- </li>
- </$:each>
Let me take the possibility to the extreme:
- <$:appendTo selector="#main">
- stuff here is injected inside the #main tag
- </$:appendTo>
- <$:if test="this.isSelected>
- <$:attr name="selected" value="true" />
- </$:if>
Forgive me if this is just a scattered collection of ideas, but my main point here is: "what if" we will be able to express jQuery functions in a declarative way? Does it open new possibilities? Is it complex to implement?
I do not know a lot about how jQuery works inside, but as far as I understand it seems to me that the template engine could work in this way: 1) parse the template as a normal DOM and 2) after (or "while" it's parsing the dom) recurse all nodes and apply specific jQuery functions where needed
This would as well leave full flexibility on what one can do whithout a pre-determined set of options on one hand, and on the other it will be a truly specific jQuery application.
Am I completely out of my mind?
Lorenzo
Re: Re: jQuery Templates Proposal
11 years ago
Such way is not W3C valid ...
As for markup language and syntax, better to leave it with regular javascript way. Direct execution of script will save tons of time on parsing markup language.
As for markup language and syntax, better to leave it with regular javascript way. Direct execution of script will save tons of time on parsing markup language.
Re: Re: jQuery Templates Proposal
11 years ago
Thank you for your comments However:
- I'm not sure which "way" you refer to which is not W3C valid. I put there such many different suggestion... I didn't want to stick to a specific sintax and I'm not expert either. But I believe that there are ways to sort out that problem. I have also inserted a possible solution using the {each ... as suggested by John.
- I think that it's when you have tags inside a javascript that you need to parse them. If you have JS embedded into tags (my way) you need to find ways to execute JS (maybe dynamic function as per John's version of the template)
- In any case my suggestions wanted just to point out different ways to look at the matter. I saw something like that around http://www.insideria.com/2009/10/jxt---javascript-xhtml-tags.html
I am not even arguing about which way is faster. I think that if people (John & Co.) could think and write a jQuery library, well... the sky is the limit.
I have been trying to implement my (theoretical) suggestions but unfortunately I'm a bit out of my depth and I need to work more on it. However there are few things to narrow down and other insights.
I will come up with some updates on the matter.
Leave a comment on lm66uk's reply
Re: jQuery Templates Proposal
11 years ago
I think this is a great idea.
For me logic inside the template is a must (i.e. for loops, if/else blocks, .. ? .. : .. ; , etc).
But a bigger priority is simply to have some html in a js variable that I want to be used as a template:
The pattern I have developed when using js and other jquery template plugins (and this has evolved over 2 years of solid use) is that for each page I esentually have a jquery plugin that I put in an external js file. As part of this external jquery plugin, I have a variable that contains the template that I want to use:
So the moral of the story is please add support out of the box to just pass in the HTML that one want to use for the template.
Hope this helps
Anthony
For me logic inside the template is a must (i.e. for loops, if/else blocks, .. ? .. : .. ; , etc).
But a bigger priority is simply to have some html in a js variable that I want to be used as a template:
- var data = { ... };
- var template = '<li>{%= data.firstName %></li>';
- $('.content').newTemplatePlugin(template, data);
The pattern I have developed when using js and other jquery template plugins (and this has evolved over 2 years of solid use) is that for each page I esentually have a jquery plugin that I put in an external js file. As part of this external jquery plugin, I have a variable that contains the template that I want to use:
- ...
- pagePlugin.Template = ' .... \
- <li>{%= data.firstName %></li> \
- .... ;
- ...
So the moral of the story is please add support out of the box to just pass in the HTML that one want to use for the template.
Hope this helps
Anthony
Leave a comment on vdh.ant's reply
Re: jQuery Templates Proposal
11 years ago
Introducing a templating system in jQuery core is something that I would hate to see.
I don’t think a templating system will fit nicely with your current feature set. AJAX, events and DOM manipulation is jQuery through and through. But a templating system? That’s something the oversized YUI library should include.
Critically for me however, jQuery is already abused by an unbelievable amount of people who see it as an easy way to do something that would traditionally be performed on the server. Converting large data sets into a HTML template is something that should always be handled by a server side language. Changing the value of a couple of element attributes; fine. Building a couple of elements; fine. Generating a table of statistics from a lengthy array of data; definitely never!
"jQuery is a fast and concise JavaScript Library that simplifies HTML document traversing, event handling, animating, and Ajax interactions for rapid web development."
Where templating fits into that description is beyond me. I would much prefer to see templating it introduced as something similar to jQuery UI.
Regards,
Matt
Re: Re: jQuery Templates Proposal
11 years ago
i disagree.
yes. for a regular websites the pages should always be generated on the server. however there are plenty of disadvantages to generating templates on the server in a webapp context where a lot of event handlers and ajax is used. if you generate templates serverside, you need to rebind most of your handlers to newly re-generated ui elements returned from the server and lose any styling that was applied based on previous UI interactions unless you heavyhandedly maintain state on each interaction.
in my opinion, in a webapp, the only reason to ever talk to a server is to receive initial markup that doesnt already exist in the DOM or exchange pure data (to maintain state, persist or query info and perform secret business logic). yes there is a performance aspect to this that may not be suitable for some mobile access apps, BUT you will always have separate UI code for mobile and you can do that serverside if needed.
ideally your initial top-level webapp sections would be straight markup from the server and your $.ready handler would simply bind the needed objects to the DOM to continue only with AJAX/data server interaction - Mustache (as suggested above) has template parsers in all server side languages of significance and also in JS, so something like this is actually quite doable.
i agree as i said before, templating doesnt belong in the core.
Leon
Leave a comment on mattlunn's reply
Re: jQuery Templates Proposal
11 years ago
The idea it's intresting but .. i believe needs some improvement in the language system. I'd prefer similar to this
http://code.drewwilson.com/entry/titan-an-introduction
http://code.drewwilson.com/entry/titan-an-introduction
Leave a comment on pm.calabrese's reply
Re: jQuery Templates Proposal
11 years ago
Hello chaps,
Since I've spent quite a lot of time working on client-side templates, I thought I would make the following points:
1) Most of the examples here involve rendering flat data structures. But templates are invaluable when used to render hierarchical structures (eg nested folders). For this reason I would recommend solving for the hierarchical case, and treating flat structures as a special case.
2) Templates can be used to render both markup and interface components. This approach can lead to a very high level of factoring and hence greatly increase compression.
3) There is always a trade-off between library size and its functionality. Personally, I believe the library should provide a wide variety of commonly used functionality, which is lazy-loaded as appropriate. This means people are not continually reinventing the wheel.
4) The ability to include one template within another is fundamental (related to point #1). Entire applications can be created using nested templates (with the associated benefits as set out in #3).
5) I chose the HTML route in conjunction with cloneNode. The issue regarding spurious src, id, values can easily be solved by prefixing them (eg _src) and only setting the correct attribute on instantiation.
6) I eschewed embedded js in the templates, preferring instead a customized substitution syntax which is compiled into a sort of 'bytecode' when the template is first loaded (for performance reasons). User-written js functions can still be referenced from within the syntax, so as to cover specific use cases.
Example syntax
- <div class = '" *is_node?<node_class><leaf_class>" ></div>
Purely to demonstrate the above points stem from hard-learned lessons, I've attached a link to a 2 minute demo video which shows an application constructed entirely from nested templates, and making heavy use of hierarchical data structures.
- David
Leave a comment on dsemeria's reply
Leave a comment on fedor.indutny's reply
Re: jQuery Templates Proposal
11 years ago
the proposal breaks xhtml in some browsers with an teampleate like this:
<script id="ul_add_apps_teamplate" type="text/html">
<li class="add-apps-li">
<input type="checkbox" name="cb_add_apl_{%= IdAppl %}" />
</li>
</script>
I propose the use of CDATA inside script
<script id="ul_add_apps_teamplate" type="text/html">
//<![CDATA[
<li class="add-apps-li">
<input type="checkbox" name="cb_add_apl_{%= IdAppl %}" />
</li>
//]]>
</script
i used this code to render the teamplate:
var x = $("#ul_add_apps_teamplate").html().replace("//<![CDATA[", "").replace("//]]>", "");
$("#ul_add_apps").empty().append(x, arr);
and mydoctype is:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN" "http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
Also i am geting some erros with firefox 3.6.3 final and google crhome 5 beta.
the rendering code is working fine in ie 8 and opera 10.5.1
Leave a comment on cesarchefinho's reply
Re: jQuery Templates Proposal
11 years ago
I really like the use cases in your github demo page, but I'm not convinced that John's tmpl plugin needs to be changed that much in order to achieve those uses. If you look over at the templating syntax discussion, I've posted some template methods that discretely add in the functionality for your use cases without changing the way tmpl works at all. {{partial}} adds in nested templates and {{count}} accesses the parentarray to expose the length property. These methods use the jQuery.tmplcmd interface without creating a separate context object.
Event binding is a different story, though. I was able to write an inline event with {{onEvent}}, but I think it will require functional changes in order to actually bind an event. On the other hand, I don't really think this is a legitimate need since the data can be embedded in the markup and then shown or hidden unobtrusively with delegate().
With the exception of bound events, have I missed any other use cases?
Are there other use cases for bound events that might make me reconsider their usefulness?
Event binding is a different story, though. I was able to write an inline event with {{onEvent}}, but I think it will require functional changes in order to actually bind an event. On the other hand, I don't really think this is a legitimate need since the data can be embedded in the markup and then shown or hidden unobtrusively with delegate().
With the exception of bound events, have I missed any other use cases?
Are there other use cases for bound events that might make me reconsider their usefulness?
Leave a comment on bradmar's reply
Re: jQuery Templates Proposal
11 years ago
Although it seems that jQuery has already decided to build on "micro-templates", I thought I'd post this here as well.
I just released a JS template engine that I'm working on for a while. I decided to write it because I have my own ideas about the syntax. :-)
The engine itself does not depend on any library (it can run outside the browser as well, i.e. with Rhino or V8) but there's a small jQuery plugin wrapper too.
I'm using it for a while now and it's quite stable and fast (templates are compiled to JS). The code is also quite small (8.5K minified) I would say, for the number of features — but clearly heavier than the "micro-templates".
I just released a JS template engine that I'm working on for a while. I decided to write it because I have my own ideas about the syntax. :-)
The engine itself does not depend on any library (it can run outside the browser as well, i.e. with Rhino or V8) but there's a small jQuery plugin wrapper too.
I'm using it for a while now and it's quite stable and fast (templates are compiled to JS). The code is also quite small (8.5K minified) I would say, for the number of features — but clearly heavier than the "micro-templates".
Leave a comment on mishoo's reply
Re: jQuery Templates Proposal
10 years ago
Hi,
I'm still trying to figure out if the proposal has a DOM requirement or not. Thus, will it run in things like Rhino and V8? I'm looking to create a server-side templating system, and I'd like parts of templates to be re-usable in a standardized in-browser templating library.
I know at this time that server-side DOM is still in its infancy, and really isn't something that I can support any time soon. Thus, I have a strong preference for templating systems that work "as-is" without the DOM.
Anyway, is this proposal getting traction? Will it run in situations without a DOM, like when using Rhino or V8?
Re: Re: jQuery Templates Proposal
10 years ago
I'm not sure about how this Microsoft version of tmpl works, but I can tell you that the J. Resig version will return a string, not a DOM element. It should work without the DOM.
I think this Microsoft version must convert to DOM at some point in the process, because it allows for event binding.
I think this Microsoft version must convert to DOM at some point in the process, because it allows for event binding.
Leave a comment on gwbasic's reply
Re: jQuery Templates Proposal
10 years ago
Yes, it has to return a string and not a DOM. John Resig micro-templating was a great start, and we are actually using it.
Mustache.js is interesting, but way to limiting. The idea to not support the "." notation is particular to say the least.
Leave a comment on jeremy.chone's reply
Re: jQuery Templates Proposal
10 years ago
Update: The official jQuery Templates plugin can now be found here: http://github.com/jquery/jquery-tmpl
For links to documentation on the current design, and for context on how the jQuery Templates plugin evolved subsequently to this discussion thread, see jQuery Templates is now an Official jQuery Plugin.
Leave a comment on Boris Moore's reply
Change topic type
Link this topic
Provide the permalink of a topic that is related to this topic
Reply to stephen.walther's idea
{"z3274852":[14737000000771845],"z3296960":[14737000000782293],"z943863":[14737000000756297,14737000000758392,14737000000763396,14737000000766428,14737000000768063,14737000000769721,14737000000786021,14737000000814837],"z3358971":[14737000000814831],"z3388470":[14737000000841360],"z3288547":[14737000000781169],"z28836":[14737000000780306],"z2950009":[14737000000787057],"z3342497":[14737000000807796,14737000000814161],"z3288421":[14737000000779689],"z4641730":[14737000001466739],"z165885":[14737000000779259,14737000000781714],"z3511869":[14737000000937022,14737000001094902],"z3239277":[14737000000770244,14737000000770275,14737000000770491,14737000000770386,14737000000770471,14737000000770473,14737000000770489,14737000000770495,14737000000770388,14737000000770493,14737000000771137,14737000000771135,14737000000771172,14737000000771204,14737000000772220,14737000000813090],"z2191048":[14737000000770710,14737000000773252],"z3167500":[14737000000743212,14737000000747432],"z3016727":[14737000000767661,14737000000766639,14737000000771162,14737000000780480,14737000000780484],"z3059313":[14737000000763305,14737000000767378,14737000000769015],"z2655461":[14737000000770050],"z3907775":[14737000000943741],"z3167546":[14737000000741540,14737000000747498,14737000000769188,14737000000769711],"z216582":[14737000000992342],"z3398782":[14737000000838487],"z2966097":[14737000000780706],"z2944156":[14737000000742573,14737000000749408,14737000000780460,14737000000781368],"z3369046":[14737000000823685],"z3456615":[14737000000888951],"z4126730":[14737000001084128],"z2952513":[14737000000781159,14737000000780496,14737000000782043,14737000000782065],"z3247939":[14737000000768143,14737000000770306],"z2958071":[14737000000785597],"z2951002":[14737000000810506],"z2566198":[14737000000751961,14737000000758290,14737000000769104,14737000000769108,14737000000769110,14737000000769160,14737000000769162,14737000000769224,14737000000769228,14737000000769240,14737000000769226],"z3292621":[14737000000785688],"z1762172":[14737000001311195],"z2976766":[14737000000779321,14737000000792882],"z3329246":[14737000000801532],"z2951261":[14737000000782993,14737000000792852,14737000000796175],"z2952694":[14737000000779397]}