PDA

View Full Version : Idea: real HTML as templates



SteveEisner
12 Nov 2006, 6:22 PM
Jack, here's an idea I had while working on some template-driven code.

Basically, after creating an app in yui+yext, the paradigm for web apps has kind of been reversed: whereas most people usually think of an application as HTML + JS support, now the JS + DOM are the "app" and the HTML becomes the support file. In other words, your HTML file ends up being a long list of DIV/etc "resources" to be used as UI templates and panels.

The one case where this breaks down is in your DomHelper.Template code. In this, you pass an HTML string as a parameter. Why not allow people to create an element in their HTML file and pass that as the template? In other words:


<div id="feedTemplate">
<a id="feed-{id}" href="{url}"><span class="body">{name}
<span class="desc">{desc}</span></span></a>
</div>

and

tpl = new YAHOO.ext.DomHelper.Template('feedTemplate');


Some advantages:
1) HTML editor support for large templates
2) You can format with newlines, etc. for readability
3) Easy to change your code to support this (getEl(x).dom.innerHTML.trim()) :)

SteveEisner
12 Nov 2006, 6:24 PM
(Note: One thing I can think of that might cause trouble is if the browser automatically wraps TRs, etc which would make it harder to make table row templates)

jack.slocum
12 Nov 2006, 7:16 PM
You can do that via innerHTML. In fact, my comment dialog initially did that but I ended up not needing it.

Since the Template class requires a string as the first param already, you'd need to create extended class or add a boolean param.

One note on this method and the primary reason I don't use it a lot (I've tried). FireFox will rewrite any links to fully qualified links and automatically replace "{" and "}" url encoded. That breaks the template. I don't know if it does this with any other elements. For example the template you supplied I initially did that way:


<div id="feedTemplate">
<a id="feed-{id}" href="{url}"><span class="body">{name}
<span class="desc">{desc}</span></span></a>
</div>

But in FireFox, it becomes:


<div id="feedTemplate">
<a id="feed-{id}" href="http://www.jackslocum.com/blog/examples/feed-viewer/%7Burl%7D"><span class="body">{name}
<span class="desc">{desc}</span></span></a>
</div>

If you think of a (simple) workaround for this, please let me know.

SteveEisner
12 Nov 2006, 7:33 PM
I don't think you'd need a param - you can pretty easily tell an ID from a valid template string, and the cost of that check would only be incurred once.

You could possibly avoid { and } url-encoding by changing the template characters, etc. or special-casing to allow %7B and %7D to work too.

I'll look for a way around the pre-pending of a base ref, but I'm not sure that actually is going to get in your way. Wouldn't firefox do the exact same thing with an href generated by your templates anyway, at the time that you stick it into the DOM? (in other words, isn't the effective DOM output the same?)

jack.slocum
12 Nov 2006, 8:26 PM
Imagine this URL: '/blog/examples/foo.php'.

When you template it from JS, you will insert this HTML into the document:

<a id="feed-{id}" href="/blog/examples/foo.php"><span class="body">{name}
<span class="desc">{desc}</span></span></a>

which FireFox will expand to:

<a id="feed-{id}" href="http://www.jackslocum.com/blog/examples/foo.php"><span class="body">{name}
<span class="desc">{desc}</span></span></a>

In the previous example, even if we made it recognize the encoded brackets, we'd end up with this:

<a id="feed-{id}" href="http://www.jackslocum.com/blog/examples/feed-viewer//blog/examples/foo.php"><span class="body">{name}
<span class="desc">{desc}</span></span></a>

Which would 404. The problem is FireFox is rewriting the URL before we put in the full path.

Another example:

JS Template:
<a id="feed-{id}" href="http://developer.yahoo.com/yui/"><span class="body">{name}
<span class="desc">{desc}</span></span></a>

innerHTML :

<a id="feed-{id}" href="http://www.jackslocum.com/blog/examples/feed-viewer/http://developer.yahoo.com/yui/"><span class="body">{name}
<span class="desc">{desc}</span></span></a>

See the problem? There probably could be some type of regex'ing to correct this - but what other elements have the same type of changes applied? I don't know the answer to that. Also, how to determine which url's need to be cleaned and which are intentional. A template could contain the full url on purpose and we'd have no way to determine that:

<a id="feed-{id}" href="http://www.jackslocum.com/blog/examples/{page}"><span class="body">{name}
<span class="desc">{desc}</span></span></a>

Here clearing out the url would break the template.

SteveEisner
12 Nov 2006, 8:56 PM
Got it. I didn't think about absolute URLs. Orphaned TR's were another example of something I could imagine a browser modifying if it were left in HTML.

I'll see if I can find a way around it! I really like the idea of the inversion from HTML as master to HTML as resource file. But if the browser continues to perform irreversible "auto-corrects" on the resources then it's a lost cause...

PowersUSA
12 Nov 2006, 9:46 PM
The template code could be hosted in a hidden textarea form element ala TrimPath http://trimpath.com/project/wiki/JavaScriptTemplates .

SteveEisner
12 Nov 2006, 11:01 PM
Clever... They've clearly faced the same issues, although they have even more need to keep it out of HTML because their advanced template language isn't even always valid HTML.

I don't know if a hidden textarea is better than a JS variable, though. I was thinking that you could get the advantage of an HTML editor being able to work with your template. If it's just a piece of text, I'm not sure there's an advantage as long as you can have a string span across multiple lines in JS?

I'll keep thinking about templating. Meanwhile I've gotten by with a really long string constant :)

jack.slocum
13 Nov 2006, 5:14 AM
Their templates are indeed much more than the DomHelper templates. Everytime I think about adding support for at least looping, I change my mind.

The textarea idea isn't bad. IMO if you are willing to build things using DOM (and who isn't?) then you should also be willing to have some small template strings there too. Obviously having large templates embedded in JS would be difficult to maintain.