Meteor UI's new templating engine - first preview release

4,244 views
Skip to first unread message

David Greenspan

unread,
Oct 15, 2013, 12:41:34 AM10/15/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
Good evening!

We are very excited to announce the first preview release for the new templating engine. This preview release contains work we've been developing on a branch, which replaces machinery such as Spark and Liverange but supports roughly the same template API as before. The new engine has simpler, easier-to-understand behavior with respect to the DOM; you don't have to use `{{#constant}}` and `preserve` directives or guard against multiple "rendered" callbacks.  jQuery plugins work well with Meteor templates. Some API changes will require porting packages and apps, but we've tried to keep the new engine as backwards compatible as possible.

This work is absolutely not yet ready for use in production apps.  In fact, it's much more unfinished than usual for code that we're soliciting feedback on.  However, there's been so much interest and excitement about Meteor UI that we think our hardcore users might be willing to help bang on a buggy version.  We're releasing this early to get feedback about the new API, to learn about bugs that can be reproduced in small apps, and to give package and app authors some time to prepare for the upcoming release. Some packages, most notably ones generating forms or implementing routing, will have to be ported first. We'll be releasing additional preview releases as we get further down the path on the track for Meteor 0.7.0.

Details about the changes and how to run the code can be found on our wiki. This page will be kept up-to-date as changes are made.


Cheers!

David and Avi

Darius Clarke

unread,
Oct 15, 2013, 3:40:55 AM10/15/13
to meteo...@googlegroups.com
Thank you! :)

Looking forward to taking it out for a spin. 

- Darius


--
You received this message because you are subscribed to the Google Groups "meteor-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to meteor-talk...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Vianney Lecroart

unread,
Oct 15, 2013, 12:03:07 PM10/15/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
That rocks!
Thank you David for letting us previewing the system.
Can't wait to use it when iron-router will work with it.

Sang Do

unread,
Oct 15, 2013, 12:14:23 PM10/15/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
That's exciting!

Thank you. 

Sang Do

Gabriel Pugliese

unread,
Oct 15, 2013, 1:45:42 PM10/15/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
What's the branch to test it ? devel ?



Gabriel Pugliese
CodersTV.com
@coderstv


David Glasser

unread,
Oct 15, 2013, 2:02:53 PM10/15/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
See the wiki page :)


--
You received this message because you are subscribed to the Google Groups "meteor-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to meteor-core...@googlegroups.com.
To post to this group, send email to meteo...@googlegroups.com.
Visit this group at http://groups.google.com/group/meteor-core.

Gabriel Pugliese

unread,
Oct 15, 2013, 2:10:28 PM10/15/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
:D



Gabriel Pugliese
CodersTV.com
@coderstv

Phuoc Do

unread,
Oct 15, 2013, 2:23:35 PM10/15/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
rendered callback on fired once. Does it behave like created but only after all elements are created? What happens if I want to use old rendered behavior (call when object update happens)?

A very frequent tracing task I do when debugging reactive update issue is to find the trigger source. It'd be incredibly helpful for meteor to tell me: Document.update(...) at line 123 in file.js causes this.

I skim through meteor UI wiki. It doesn't seem to have anything that addresses this issue.

On Monday, October 14, 2013 9:41:34 PM UTC-7, David Greenspan wrote:

Ken Yee

unread,
Oct 15, 2013, 5:04:07 PM10/15/13
to meteo...@googlegroups.com, meteo...@googlegroups.com


On Tuesday, October 15, 2013 2:23:35 PM UTC-4, Phuoc Do wrote:
rendered callback on fired once. Does it behave like created but only after all elements are created? What happens if I want to use old rendered behavior (call when object update happens)?

Why would you want to?
This was the most annoying part of the rendered callback when you tried using any jquery plugins :-)

The other changes look good too, but this will break pretty much every Meteor app in existence w/ all the syntax changes:-P
It's all for the better though...

Avital Oliver

unread,
Oct 15, 2013, 8:05:21 PM10/15/13
to meteo...@googlegroups.com
On Tue, Oct 15, 2013 at 11:23 AM, Phuoc Do <dnp...@gmail.com> wrote:
rendered callback on fired once. Does it behave like created but only after all elements are created? What happens if I want to use old rendered behavior (call when object update happens)?
That's right. As far as we could tell, not many users liked the original rendered behavior. That being said, here's an example of two ways to achieve the same results with the new system, for a small sample app. Does it resolve your concern?

 
A very frequent tracing task I do when debugging reactive update issue is to find the trigger source. It'd be incredibly helpful for meteor to tell me: Document.update(...) at line 123 in file.js causes this.
Actually, in the current system you can stop at a breakpoint when a helper is called. The stack trace will include the original collection-modifying code that caused the helper to get called. If the change was caused by a session variable it's a little harder to track, since Deps coalesces changes into one call to Deps.flush, but I believe it's still easier to track than before.

I agree that a general way to track how reactive changes lead to DOM updates would be great, but that's not in scope for this release. This could be a third party package.

On Monday, October 14, 2013 9:41:34 PM UTC-7, David Greenspan wrote:
Good evening!

We are very excited to announce the first preview release for the new templating engine. This preview release contains work we've been developing on a branch, which replaces machinery such as Spark and Liverange but supports roughly the same template API as before. The new engine has simpler, easier-to-understand behavior with respect to the DOM; you don't have to use `{{#constant}}` and `preserve` directives or guard against multiple "rendered" callbacks.  jQuery plugins work well with Meteor templates. Some API changes will require porting packages and apps, but we've tried to keep the new engine as backwards compatible as possible.

This work is absolutely not yet ready for use in production apps.  In fact, it's much more unfinished than usual for code that we're soliciting feedback on.  However, there's been so much interest and excitement about Meteor UI that we think our hardcore users might be willing to help bang on a buggy version.  We're releasing this early to get feedback about the new API, to learn about bugs that can be reproduced in small apps, and to give package and app authors some time to prepare for the upcoming release. Some packages, most notably ones generating forms or implementing routing, will have to be ported first. We'll be releasing additional preview releases as we get further down the path on the track for Meteor 0.7.0.

Details about the changes and how to run the code can be found on our wiki. This page will be kept up-to-date as changes are made.


Cheers!

David and Avi

Tim Heckel

unread,
Oct 16, 2013, 11:32:36 AM10/16/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
This is fantastic. Thanks for all the great work. I plan on taking a closer look soon..

Jonathan Dumaine

unread,
Oct 16, 2013, 10:44:43 PM10/16/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
This is so incredibly cool. It remind me a lot of Ember's smart bindings. 

I couldn't even begin to wrap my head around the complexity of accomplishing this. Great job!



On Monday, October 14, 2013 9:41:34 PM UTC-7, David Greenspan wrote:

Carl Littke

unread,
Oct 21, 2013, 3:15:31 AM10/21/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
Nice job! I think this will make development quite a bit easier.

When using a template I think it would make a lot of sense to allow passing false as the value of a variable. Atm passing any value seems to evaluate to true.

<template name="li">
  <li>
  {{#if edit}}
    <input type="text" value="{{this}}">
  {{else}}
    {{this}}
  {{/if}}
</li>

<ul>
  {{> li edit=false}}
</ul>

This will result in the input being displayed.

Tim Heckel

unread,
Oct 21, 2013, 12:31:59 PM10/21/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
One question -- if the syntax for accessing parent properties is gone, I'm wondering how I can get at that data inside my nested {{each}}s ? (https://github.com/meteor/meteor/wiki/New-Template-Engine-Preview#no-more-)

Or are you suggesting a different pattern for getting at this data?

On Monday, October 14, 2013 11:41:34 PM UTC-5, David Greenspan wrote:

Thomas Haferlach

unread,
Oct 21, 2013, 4:59:24 PM10/21/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
i'm testing my current project with the new release and it seems it has broken my event maps. 

is there any change to the event map syntax? i couldn't find anything specific in the wiki

Silly Clown

unread,
Oct 21, 2013, 5:06:06 PM10/21/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
I think this pattern could work to initialize and set parent context...

Template.superForm.created = ->
  Template.superForm.tooltipX = =>
     Template['tooltip'].withData(@data)

Dirk Porsche

unread,
Oct 22, 2013, 3:30:06 AM10/22/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
Hi,

what is the schedule for making textarea functional?

Regards
Dirk

Dirk Porsche

unread,
Oct 22, 2013, 3:31:19 AM10/22/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
You can include a reference to the parent in the objects your iterating over.

Avital Oliver

unread,
Oct 22, 2013, 7:11:57 PM10/22/13
to meteo...@googlegroups.com
Hi Thomas,

There shouldn't be any changes to the event map syntax. If you can produce a small repro of the bug as a cloneable Git repository we'll look at it.

Avital Oliver

unread,
Oct 22, 2013, 7:42:10 PM10/22/13
to meteo...@googlegroups.com
Carl, this indeed looks like a bug. Thanks for the repro! I'm looking into it.

--

Avital Oliver

unread,
Oct 23, 2013, 1:40:03 AM10/23/13
to meteo...@googlegroups.com
Hi Carl,

I fixed the bug you reported[1] and created a new release named 'template-engine-preview-1'. Let me know if this resolves your issue. Thanks once again!

Cheers,
Avital.

Dirk Porsche

unread,
Oct 24, 2013, 8:54:32 AM10/24/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
Hi,

I'm playing around with the new templating engine for some days know. It sounds quite promising, but I've found some things I don't really get. Maybe you could shed some light upon those things.

First, why is a Template helper called multiple times. Once for every attribute I'm accessing, or trying to access.

I have this template code in the basic Hello example:

<head>
  <title>test</title>
</head>

<body>
  {{> hello}}
</body>

<template name="hello">
    <h1>Hello World!</h1>
    {{#with obj}}
    {{> other}}
    {{/with}}
</template>

<template name="other">
    {{test1}}
    {{test2}}
    {{test3}}
</template>

And this Template helper:

if Meteor.isClient
    count = 0
    Template.hello.obj = () ->
        console.log 'called: ' + count += 1

The old engine called the obj helper once. The new one thrice, once for every attribute (or sub helper I'm trying to access)

Is this behaviour intended? I used to instantiate objects in the helper to handle stuff down to the nested templates. Now I have conflicts there, because I can't be sure which instance I will end up with, in the final rendering. This is especially annoying when forking templates with an #if based on some calculations.

I guess it's good practice to have functions that return the same value given the same input, but as soon as you rely on data from a collection things get complicated.

There are more things I will try to isolate and report soon.

Regards
Dirk

Am Dienstag, 15. Oktober 2013 06:41:34 UTC+2 schrieb David Greenspan:

David Greenspan

unread,
Oct 24, 2013, 9:40:56 AM10/24/13
to meteo...@googlegroups.com
Very interesting point.  Probably {{#with obj}} should indeed call obj once, and create a ReactiveVar that gets accessed when the value is used.

What's new here is we used to handle invalidated data by re-rendering whole templates, whereas now the data flows down to the places where values are inserted into the DOM, which are re-rendered individually.

-- David

Carl Littke

unread,
Oct 24, 2013, 2:32:14 PM10/24/13
to meteo...@googlegroups.com
@Avital

My pleasure. I really appreciate the work you put into this. Passing false to the template works nicely now. 

I noticed that the value is assigned to tmpl.__component__. You probably already thought about this but I think it makes more sense to hide the values behind a data attribute on the component to avoid conflicts with the components own namespace. 

E.g. this will show the input since the component have a dom attribute.

{{> li dom=false}} 

<template name="li">
  <li>
  {{#if dom}}
    <input type="text" value="{{this}}">
  {{else}}
    {{this}}
  {{/if}}
</li>


On a related subject:
Updating a template variable after it has been instantiated - as in the following example - does not update the template, but I guess that's not to be expected at this point?

{{> li edit=false}} 

<template name="li">
  <li>
  {{#if edit}}
    <input type="text" value="{{this}}">
  {{else}}
    {{this}}
  {{/if}}
</li>

Template.li.events({
  'click li':function(e, tmpl) {
    tmpl.__component__.edit = true;
  }
});

Dirk Porsche

unread,
Oct 24, 2013, 2:55:36 PM10/24/13
to meteo...@googlegroups.com
Hi David,

from my naive framework-user-viewpoint, it would be great if everything that gets accessed from a template is automatically becoming a reactive var. This might be short-sighted, though.

Here is another unexpected thing I found out. 

I used to encapsulate event triggers in functions and add them to the templates as appropriate. This code worked in the old engine and isn't functional in the new one. The event isn't triggered.

if Meteor.isClient
    
    updateEvent = (p) ->
        'keyup input': (e) ->
            console.log e
            newValue = e.target.value
            p.value = newValue
    
    Template.hello.obj = () ->
        p = 
            value: 'Initial'
            label: 'Label'
        Template.hello.events = updateEvent p
        p


<head>
  <title>fields-simple</title>
</head>

<body>
  {{> hello}}
</body>

<template name="hello">
    <h1>Hellow World!</h1>
    {{#with obj}}
    <label>{{label}}</label>
    <input type="text" value="{{value}}">
    {{/with}}
</template>


By the way, should I open issues on GitHub for this? Or is here the appropriate place.

Regards Dirk
To unsubscribe from this group and stop receiving emails from it, send an email to meteor-talk+unsubscribe@googlegroups.com.

Dirk Porsche

unread,
Oct 24, 2013, 3:07:01 PM10/24/13
to meteo...@googlegroups.com
Me again.

Just one minor thing, I guess. The old engine realized when there was more than one template with the same name. The new engine doesn't complain.

Regards
Dirk

David Greenspan

unread,
Oct 24, 2013, 10:27:53 PM10/24/13
to meteo...@googlegroups.com
Ah, Meteor should complain when there's a duplicate template name (to match current behavior).

    updateEvent = (p) ->
        'keyup input': (e) ->
            console.log e
            newValue = e.target.value
            p.value = newValue
    
    Template.hello.obj = () ->
        p = 
            value: 'Initial'
            label: 'Label'
        Template.hello.events = updateEvent p
        p

This pattern doesn't seem like it will work in general.  Template.hello.events(...) is meant to be used to declare events that will apply to all instances of Template.hello.  The `events =` syntax is mainly for backwards compatibility, and changing the event map at all from a helper (called while rendering a particular instance of Template.hello) is not an intended use.

Isn't `this` the same as `p` in the event handler, anyway?

I like the spirit of using `{{#with obj}}` to create a local mutable object.  Unfortunately, there's the issue of `obj` getting called multiple times which you ran into, and there's also the problem that Meteor can't detect when you set `p.value`; data context objects are meant to be immutable at the moment.  We're still trying to figure out the best pattern for local mutable state.

-- David

Morten Henriksen

unread,
Oct 25, 2013, 2:31:31 AM10/25/13
to meteo...@googlegroups.com
I like the spirit of using `{{#with obj}}` to create a local mutable object.  Unfortunately, there's the issue of `obj` getting called multiple times which you ran into, and there's also the problem that Meteor can't detect when you set `p.value`; data context objects are meant to be immutable at the moment.  We're still trying to figure out the best pattern for local mutable state.

David - one could use Object.defineProperty for this?

I played around with this some time ago: 

Object.observe is no way near standard - but there exists some polyfills

Morten Henriksen

unread,
Oct 25, 2013, 2:34:13 AM10/25/13
to meteo...@googlegroups.com
Almost forgot, theres a brief readme with a short example of what the code does: https://github.com/raix/reactive/blob/master/README.md

Dirk Porsche

unread,
Oct 25, 2013, 2:40:31 AM10/25/13
to meteo...@googlegroups.com
Hi David,

you are right. this and p are the same. And moving the Events definition outside of the template helper made it work. I tend to always forget, that this in the event callback is the actual context of the template instance. This implementation is actually really great and makes things simple. But I always forget about it.

Just stumbled upon the different behaviour. Never mind.

Thanks for replying, though
Dirk

Avital Oliver

unread,
Oct 25, 2013, 4:57:52 PM10/25/13
to meteo...@googlegroups.com
Carl, `tmpl.__component__` is private and should not be accessed by applications. You're right that we should spend a little more time thinking about naming conflicts with the component namespace.

David Greenspan

unread,
Oct 25, 2013, 5:02:03 PM10/25/13
to meteo...@googlegroups.com
Thanks Dirk, it's very helpful to get these kinds of questions and feedback that are specific to the Meteor UI rendering model.  Your email was very useful!

Thanks,
David

On Thursday, October 24, 2013, Dirk Porsche wrote:
--
You received this message because you are subscribed to the Google Groups "meteor-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to meteor-talk...@googlegroups.com.

Abigail Watson

unread,
Oct 27, 2013, 8:21:17 PM10/27/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
Hi David & Avi!
Hey, I just ran the new preview release against my reactive rendering tests, and everything looks fantastic.  Like, the rendering patterns are real tight and consistent, and much closer to what one would not only intuitively expect, but would formally expect.    There are a couple things I'm finding though that have raised an eyebrow, though.  First, in FlockA, parent templates of an #each block don't ever seem to have a render event.  It went from 9 renders to 0 renders.  I would have expected 1 render.  Secondly, in tests that include a Session variable, I noticed that there was occasionally some lost Session state, and things would revert back to the Session.setDefault() value unexpectedly.  (I'm trying to see if I can replicate the issue consistently.)

Is there a way to deploy onto meteor with the preview release, so I can share the results?   I tried the following, which didn't work:
sudo meteor --release template-engine-preview-1 --deploy meteor-ui-rendering-tests-1.meteor.com

Nonetheless, when running the reactive-rendering-tests suite on the new rendering engine, the numbers are coming out real tight.  Congratulations!  Great work.  
Abigail 

David Greenspan

unread,
Oct 28, 2013, 3:34:16 PM10/28/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
Hi Abigail,

There should be no `--` before `deploy`.  You also shouldn't need `sudo` for this:

> meteor --release template-engine-preview-1 deploy meteor-ui-rendering-tests-1.meteor.com

You can pass a `--release` option to `meteor`, `meteor deploy`, and `meteor update`.  If you pass it to `meteor update`, it will pin your app to that release.  The other two just run or deploy your app using that release.

Thanks for the independent testing!  I'd love repros for the odd behavior you're seeing.

-- David





Gadi Cohen

unread,
Oct 29, 2013, 7:05:40 PM10/29/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
Hey, I have some bugs to report :)  Is this the right place?

#1 - template-engine-preview-2 removes handlebars

This is a problem because of issue #1358 ("Can't add weak dependencies on non-existent packages"), at least when developing packages that should ideally work with both handlebars and UI (in this case, without explicitly requiring spacebars).  I guess a workaround could be to include 'standard-app-packages' instead.

#2 - Child template wrapped in div calls rendered() before DOM is fully rendered

test.html:

<code>
<template name="parent1">
{{> child1}}
</template>

<template name="parent2">
<div>
{{> child2}}
</div>
</template>

<template name="child1">
<div id="child1">child1</div>
</template>

<template name="child2">
<div id="child2">child2</div>
</template>

test.js:

if (Meteor.isClient) {
Meteor.startup(function() {
// Parent1: works as expected
UI.insert(UI.render(Template.parent1), document.body);

// Parent2: fails when child template is wrapped in a div
UI.insert(UI.render(Template.parent2), document.body);
})

Template.child1.rendered = function() {
console.log('#child1 exists now: ' + !!$('#child1').length);
}
Template.child2.rendered = function() {
console.log('#child2 exists now: ' + !!$('#child2').length);
}
}

Returns:


Note: #child2 is available after UI.insert completes, just not when Template.child2.rendered() is run.

Hope that makes sense, it's late :)

David Greenspan

unread,
Oct 29, 2013, 7:32:56 PM10/29/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
Hi Gadi,

#2 (rendered called before template is in the document) is actually how we implemented it in the new code, but as you point out, this is different from before, so we should probably pay more attention to it since users are presumably trying to do what you're doing.  Also, in the current docs we say something like, rendered fires when the template is "put into the document for the first time."

Our intent is to move to a world where a template/component can be initialized without necessarily being in the document.  "rendered" will wait to fire only until the template's top-level DOM nodes have been parented under some element (rather than a document fragment, say), at which point it is safe to operate on the DOM and attach event handlers.  Writing in this style will be facilitated by a function `this.$` which you can use instead of `$` in the rendered callback to search only the component's DOM.

#1 - I don't know the answer to this one!

Thanks,
David




--
You received this message because you are subscribed to the Google Groups "meteor-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to meteor-core...@googlegroups.com.
To post to this group, send email to meteo...@googlegroups.com.
Visit this group at http://groups.google.com/group/meteor-core.

Gadi Cohen

unread,
Oct 30, 2013, 3:44:13 AM10/30/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
Hey David

Wow, thanks for the super fast reply there! :>

Ok, got it.  Understanding that, $(this.find(selector)) seems to work fine for now (as would findAll for multiple elements).  Won't complain for the convenience of a this.$ :)

I imagine this might break some jQuery plugins, depending on how they are written (i.e. relying on nodes already being in the document).  I can see the advantages of firing rendered() as described, but wonder if maybe it would be good to have another callback for when the template is fully loaded in the document.  Not sure how easy that is to implement, but could help with some situations (compatibility with external libraries).  For Meteor specific code on the other hand, I quite like what you've described.

Best,
Gadi 

Matt Steedman

unread,
Oct 30, 2013, 12:37:48 PM10/30/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
Hey guys I just checked out the new rendering engine and so far it's fantastic! I have run into at least one bug that I've been able to reproduce, however. It has to do with using {{#each}} to iterate over a cursor. Here is a link to the Github repo that replicates the problem: https://github.com/knubie/meteor-render-bug

The 'messages' cursor gets returned from a template helper, but only if the user is signed in. The problem is, that if the user's profile gets updated, the order of messages in the DOM get's mixed up.

Steps to reproduce:
1. Sign up
2. Add some messages.
3. Click the button that modifies the user's profile. (At this point you'll see some errors in the console, but it doesn't affect the DOM, this step is actually optional)
4. Refresh the page.
5. Add another message or more.
6. Click the button that modifies the user's profile. (You'll get the same errors in the console as before, but this time the messages that were added since the page was refreshed get moved up to the top of the list.)

So hopefully that makes sense, if you have any questions definitely let me know. And once again great work on the new engine! Can't wait till 1.0

Avital Oliver

unread,
Oct 30, 2013, 9:49:42 PM10/30/13
to meteo...@googlegroups.com
Hi Matt, thanks for the reproduction.

This is indeed a bug with helpers switching between two cursors or between a cursor and an array. I'll try to get a fix out soon.


--
You received this message because you are subscribed to the Google Groups "meteor-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to meteor-talk...@googlegroups.com.

Matteo De Micheli

unread,
Nov 1, 2013, 3:44:57 PM11/1/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
Great news! Looking forward to finally using it :)


Am Dienstag, 15. Oktober 2013 06:41:34 UTC+2 schrieb David Greenspan:

Avital Oliver

unread,
Nov 1, 2013, 9:27:31 PM11/1/13
to meteo...@googlegroups.com
Good evening Matt,

We believe we've fixed your app's problem on the `shark` branch and the new `template-engine-preview-3` release. The issue occurred any time {{#each}} fires on a reactive function that changes between different arrays or cursors. This also mostly improves performance of {{#each}} on arrays of objects with `_id` fields by diffing them, leading to less DOM mutations. For example, this should resolve issue #1544.

Give it a whirl by running `meteor update --release template-engine-preview-3` in your app directory. Let us know if it resolves your problem and anything else that comes up.

Have a great weekend,
Avital and Slava.
Message has been deleted

Abigail Watson

unread,
Nov 3, 2013, 8:05:55 PM11/3/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
Hi David,
Thanks for spotting that typo in the deploy line. Finally got the results posted.  I haven't seen the session state dropping in the last couple times I ran the tests, so I think it was just something with the first time I ran the app.  Anyhow, here are the numbers and all...

Spark Reactive Rendering Tests

Matt Steedman

unread,
Nov 4, 2013, 9:57:48 AM11/4/13
to meteo...@googlegroups.com
Avital, the new release does indeed fix the bug, both in the reproduction app and on my production app where i spotted it in the first place. Great job, can't believe how fast you guys fixed that!

I've also picked up another bug that I've been trying to pin down and reproduce and I think I've finally got it to the point where I can share it with you. I believe it's related to issue #1536. These might actually be two separate bugs. I've updated the same reproduction app to show it. Now I'll try to explain what's going on.

1. Each time an item in the list is clicked it changes a Session variable called 'foo'. Each time that variable changes, the amount of times `Template.main.data` gets called increases.
2. In addition to that each time `Session.get('foo')` changes the amount of times `Template.message.rendered` gets called increases after clicking the 'switch collection' button. 

I imagine this might have something to do with the handlebars helper i made that loads a template based on `Session.get('page')`

Dirk Porsche

unread,
Nov 5, 2013, 4:12:58 AM11/5/13
to meteo...@googlegroups.com
Hi Matt,

I was able to reproduce 1.

But for 2, I just reloaded the page and clicked on the switch button multiple times and the log output doesn't change. I guess it is only in conjunction with 1 that the second problem arises.

Regards
Dirk

Dirk Porsche

unread,
Nov 5, 2013, 9:07:11 AM11/5/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
Hi David,

I have found another "issue". Or maybe I just need an advice.

I'm currently trying to get MindMup's wysiwyg editor functional (https://github.com/mindmup/bootstrap-wysiwyg), and it works somewhat in the old rendering engine. Unfortunately I stumbled upon a problem in Meteor UI.

You can find the Meteor project here: https://github.com/Crenshinibon/fields-rich2

I get an error in the browser when the page loads with the new templating engine. I'm trying to initialize the editor in the rendered callback. Unfortunately the element from the collection doesn't seem to be available (data is undefined). I guess the subscription isn't ready, yet. In the old world this wasn't an issue.

How am I supposed to handle this situation? Do I have to "wait" for the collection to be ready? I tried different strategies, but nothing seems really to work. I'm puzzled.

Thanks and best regards
Dirk


Am Dienstag, 15. Oktober 2013 06:41:34 UTC+2 schrieb David Greenspan:

David Greenspan

unread,
Nov 5, 2013, 11:55:14 AM11/5/13
to meteo...@googlegroups.com
Hi Dirk,

We made a change to "rendered" where it fires sooner, before the template is in the document (it is guaranteed to have a parent element, but that element may still be in a document fragment).  You can use this.find from rendered, but not global $, which searches the document.  That said, we're planning to change it back this week so that "rendered" waits until the template is in the document, because the change is causing confusion.

I notice that you are making an even stronger assumption about how rendered works, though.  You have a template with:

```
{{> toolbar}}
{{> editor}}
```

And then you assume that from editor's "rendered," the toolbar is in the document.  When we make rendered wait again, that will *probably* be guaranteed, but it's pretty complicated to reason about compared to putting the code that initializes the editor on a template that includes the toolbar.

Thanks,
David

Avital Oliver

unread,
Nov 5, 2013, 2:11:03 PM11/5/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
Nikolai, glad you're enjoying the new template engine!

The current preview release doesn't support block helpers yet (such as `{{#if}}`) inside element attributes (such as `class`). This is for technical, not principled reasons. David is working on a new render buffer API that will resolve this. It should land on the shark branch rather soon. We'll build a new preview release then.


On Tue, Nov 5, 2013 at 4:27 AM, Nikolai Sivertsen <nikolai....@gmail.com> wrote:
Thanks for your work, I really like where the template engine is going!

My app works with template-engine-preview-3, with one little problem: I had to remove {{#if isActive 'someView'}}selected{{/if}} from my CSS class declarations for highlighting the current view in the navigation. #if tags don't seem to work inside class declarations anymore. What's the reason for this? When I replaced it with a {{selected 'myView'}} helper that compares 'myView' to a Session variable it worked.

I get this error message:

packages/spacebars/spacebars.js:287: Can't use this stache tag at this position in an HTML tag, at line 57, offset 36 in Template "sidebar" (compiling client/views/common/sidebar.html)

Thanks!

--
You received this message because you are subscribed to the Google Groups "meteor-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to meteor-core...@googlegroups.com.
To post to this group, send email to meteo...@googlegroups.com.
Visit this group at http://groups.google.com/group/meteor-core.

Fabian Vogelsteller [tunedin.de]

unread,
Nov 5, 2013, 2:26:18 PM11/5/13
to meteo...@googlegroups.com
i definitely prefer the rendered callback AFTER its in the dom. i used it right now for animations where i removed a specific css class, when the template was in the DOM to start an CSS transition.

i realized that this was not happening anymore, probably because of your change. My workaround was to put it inside a Meteor.setTimeout, to make sure, its in the DOM when removing the class.

so i appreciate you roll back.


Fabian Vogelsteller
Web Developer

TunedIn Media GmbH
Mulackstr. 19
10119 Berlin
Mobile: +49 1577 156 80 60
E-Mail: fabian.vo...@tunedin.de
Homepage: www.tunedin.de

Registergericht: Amtsgericht Charlottenburg, Handelsregister HRB 133483B
Geschäftsführer: Sebastian Bartz, Kaspar Jost Klippgen, Justin E Scull

This message may contain confidential and/or privileged information. If you are not the addressee or authorized to receive this on behalf of the addressee, you must not use, copy, disclose or take any action based on this message or any information herein. If you have received this message in error, please advise the sender immediately by reply e-mail and delete this message. Thank you for your cooperation.

You received this message because you are subscribed to a topic in the Google Groups "meteor-talk" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/meteor-talk/gHSSlyxifec/unsubscribe.
To unsubscribe from this group and all its topics, send an email to meteor-talk...@googlegroups.com.

Dirk Porsche

unread,
Nov 5, 2013, 3:16:14 PM11/5/13
to meteo...@googlegroups.com
Hi David,

thanks for the hint, regarding the editor <> toolbar, rendered issue. Do I understand you right, that you suggest to put the initialization in the surrounding template.rendered callback (or combine them in one)?

I will keep that in mind.

Thanks,
Dirk
To unsubscribe from this group and stop receiving emails from it, send an email to meteor-talk+unsubscribe@googlegroups.com.

Dirk Porsche

unread,
Nov 6, 2013, 1:04:30 AM11/6/13
to meteo...@googlegroups.com
Hi David,

I have thought about your answer (and my question).

And actually I don't think it's a problem with the DOM element not being there. I have altered the example a little bit, now it's not making any sense, but highlights the problem better, I guess.

In the Template.editor.rendered callback I'm just trying to access the context (@data) and log it's description property. I get an error, saying @data is undefined, and it really is.

From the base template, I'm handing an element, queried from Meteor Collection, down to the nested one:

Helper:
Template.hello.description = () ->
        Test.findOne()
    
Template:
{{> richtext description}}

Trying to Access:
Template.editor.rendered = () ->
        console.log @data.description


I think the problem arises, because the template rendering isn't waiting for it's context to be set (the collection's subscription is not ready by then). I guess it's basically the same issue with #with we have talked about above.

A template should not be rendered when it's context is undefined. Or better the rendering should wait until the context is there. I guess the old implementation is doing something similar. Since I don't get errors during the earlier renderings (the context can't be possibly defined, by then).

But maybe I'm doing it (again) not in the intended way. It's a really basic question and I'm hesitating to ask, but how is this supposed to work? To render a template based on documents from a collection. I can't come up with a simple and nice looking strategy to not run into this basic problem.

Ugly and complex might work: for example one could wait for the subscription handle to be ready (but what about autopublish), or put some timeouts everywhere.

Thanks again,
Dirk
 

Am Dienstag, 5. November 2013 17:55:14 UTC+1 schrieb David Greenspan:
To unsubscribe from this group and stop receiving emails from it, send an email to meteor-talk+unsubscribe@googlegroups.com.

David Greenspan

unread,
Nov 6, 2013, 2:15:36 AM11/6/13
to meteo...@googlegroups.com
Hi Dirk,

In general, Meteor doesn't have a concept of "not-yet-loaded data" in templates, and it doesn't know that a particular `null` from a `findOne()` is a fatal issue and should stop or defer rendering.  It's up to you to guard template code against nulls, for example by wrapping a template in an #if block.

This can definitely be a pain at times, and there's an opportunity for us to provide a facility that would help.  Not rendering templates when they have "undefined" data is an interesting idea.  Another one I heard a while back is having a special "not ready" exception you can throw from your view code.  Another is to automatically determine whether a template is loaded and provide a syntax for specifying content to be displayed during loading.  We are in favor of having a facility along these lines, but it would be added post-1.0.

As for what changed, though, I think I know.  We discovered in our work that #with (on master) doesn't render its body if its argument is falsy.  This rule didn't ring any bells for us, and we couldn't find any basis for it in Handlebars documentation or behavior, so we decided it was simply a bug and fixed it.  Since {{> foo bar}} is compiled to {{#with bar}}{{> foo}}{{/with}}, the bogus "rule" also applied to this case.

Thanks for bringing this up; I'll put it on the list of stuff to think about for release.

-- David



To unsubscribe from this group and stop receiving emails from it, send an email to meteor-talk...@googlegroups.com.

Dirk Porsche

unread,
Nov 6, 2013, 2:29:34 AM11/6/13
to meteo...@googlegroups.com
Hi David,

that helps.

Thanks again
Dirk

David Glasser

unread,
Nov 6, 2013, 2:33:01 AM11/6/13
to meteo...@googlegroups.com
The {{#with falsey}} behavior was a feature added in 0.6.6, suggested by a few users.  https://github.com/meteor/meteor/issues/770

David Greenspan

unread,
Nov 6, 2013, 2:43:25 AM11/6/13
to meteo...@googlegroups.com
Oh snap!  Thanks Glasser.  We'll keep the behavior that's on master, done deal.

-- David

Dirk Porsche

unread,
Nov 6, 2013, 4:44:54 AM11/6/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
Hi David, 

it's me again. I stumbled upon two other possible issues.

As mentioned above I'm trying to integrate a rich-text editor. The one I'm trying to use (https://github.com/mindmup/bootstrap-wysiwyg) uses a div element and contenteditable.

The first issue is more a question, I guess. Inside the editor div the stored HTML code shouldn't be escaped. I'm currently returning a Handlebars.SafeString for this and it still works with the new rendering engine, but since Handlebars is moved out, the question is, what will replace this functionality?

The second is more of a real issue. I'm updating the stored value (displayed in the editor div) on user input (keyup, in the updated example). Unfortunately this leads to a reload of the editor contents. I guess this can't be easily circumvented in the new rendering engines paradigm, since the the DOM elements are actually changed.

In the old engine, wrapping {{safeDesc}} in {{#constant}}{{/constant}} results in the intended behaviour: Letting you write flawlessly and saving the changes "in the background". I guess we need something similar in the new engine. Or maybe updates on sub-DOM-element level (character-level?). At least in some circumstances ...

Thanks again. Best regards

Gadi Cohen

unread,
Nov 6, 2013, 5:57:35 AM11/6/13
to meteo...@googlegroups.com
David, Dirk and others:


On Tuesday, November 5, 2013 6:55:14 PM UTC+2, David Greenspan wrote:

We made a change to "rendered" where it fires sooner, before the template is in the document (it is guaranteed to have a parent element, but that element may still be in a document fragment).  You can use this.find from rendered, but not global $, which searches the document.  That said, we're planning to change it back this week so that "rendered" waits until the template is in the document, because the change is causing confusion.

I agree the change is confusing; there's an assumption that 'rendered' means 'rendered in the document'.  BUT:

1) Since jQuery can take an HTML node as an argument, it's still possible to use (with the current preview release), a $(this.find('selector')).  Also as David mentioned back then, there will be a this.$() shortcut for this in the future.

2) Assuming there were some performance incentives for firing the callback at this earlier stage, it could be worthwhile to have an additional hook (with a clearer name) that would still fire at this same time, for developers willing to write Meteor specific code.

Gadi

David Greenspan

unread,
Nov 6, 2013, 3:17:29 PM11/6/13
to meteo...@googlegroups.com
Gadi,

We're still considering having another callback like "parented" or "attached," but I think we can wait on that for the moment.  I don't think we lose anything by preserving the behavior of "rendered" (i.e. it waits until the template is in the document) in this release.

-- David




--

David Greenspan

unread,
Nov 6, 2013, 3:58:31 PM11/6/13
to meteo...@googlegroups.com
Dirk,

There's still triple-stache -- {{{desc}}} -- and there will remain something functionally equivalent to SafeString.

To keep the HTML from updating reactively, in theory Deps.nonreactive would help for a case like this.  Since the stache tag is now only updated when the value of the helper changes through reactive invalidation, we'd wrap the body of the helper in Deps.nonreactive to "absorb" any invalidations triggered by the contents:

```
safeDesc: function () {
  var self = this;
  return Deps.nonreactive(function () {
    return calculateDescription();
  });
}
```

However, since all helpers receive the current data context in `this` as a plain object (and Meteor doesn't know how or if that object is used), it's currently not possible to keep a helper from re-rendering if its data context changes.

Maybe there is still a use for the `{{#constant}}` helper after all.

It's surprisingly hard to come up with a workaround that doesn't use private or future APIs, but I think a straightforward one is to use the code above and where it says `calculateDescription`, do a database query there to get the description.  Then make the call to safeDesc *not* happen in a data context that depends on the description.  So something like:

```
{{#with thingId}}
  {{{constantDesc}}}
{{/with}}
```

```
constantDesc: function () {
  var thingId = String(this);
  return Deps.nonreactive(function () {
    return Things.findOne(thingId).description;
  });
}
```

The `thingId` in `{{#with thingId}}` has to not come out of the database and not be a helper function.  It should refer back to the original key used to look up the database object.  It could be `../../thingId` or something.

A better answer for this release might be to supply a `{{#constant}}` helper.  The API changes I'm working on will also provide a way to define constantDesc as a helper with full control over its reactivity, so there will be a few lines of code you can write in a helper to insert truly constant content.  There's a way now, but it's about to change, so I don't want to go into detail.

Hope this helps, and thanks for the discussion!

-- David

    


Dirk Porsche

unread,
Nov 7, 2013, 4:07:11 AM11/7/13
to meteo...@googlegroups.com
Hi David,

thank you very much. I will try to wrap my head around your suggestions and see if can come up with something. 

I'm looking forward to the next release. Thanks for your efforts.

Best regards,
Dirk

Avital Oliver

unread,
Nov 8, 2013, 6:55:06 PM11/8/13
to meteo...@googlegroups.com, David Glasser, Dirk Porsche
Dirk and Glasser,

We've made behavior of {{#with}} match the old behavior on the new `template-engine-preview-4` release.

Avital Oliver

unread,
Nov 8, 2013, 6:58:18 PM11/8/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
Hi fellow cutting-edge experimenters!

We've just released `template-engine-preview-4` in which SELECT tags work. We've also made `{{#with falseyValue}}` behave like it does on the released version of Meteor. The wiki page has been updated.

Try it out and let us know of any problems!

Thanks,
Avital.


On Mon, Oct 14, 2013 at 9:41 PM, David Greenspan <da...@meteor.com> wrote:
Good evening!

We are very excited to announce the first preview release for the new templating engine. This preview release contains work we've been developing on a branch, which replaces machinery such as Spark and Liverange but supports roughly the same template API as before. The new engine has simpler, easier-to-understand behavior with respect to the DOM; you don't have to use `{{#constant}}` and `preserve` directives or guard against multiple "rendered" callbacks.  jQuery plugins work well with Meteor templates. Some API changes will require porting packages and apps, but we've tried to keep the new engine as backwards compatible as possible.

This work is absolutely not yet ready for use in production apps.  In fact, it's much more unfinished than usual for code that we're soliciting feedback on.  However, there's been so much interest and excitement about Meteor UI that we think our hardcore users might be willing to help bang on a buggy version.  We're releasing this early to get feedback about the new API, to learn about bugs that can be reproduced in small apps, and to give package and app authors some time to prepare for the upcoming release. Some packages, most notably ones generating forms or implementing routing, will have to be ported first. We'll be releasing additional preview releases as we get further down the path on the track for Meteor 0.7.0.

Details about the changes and how to run the code can be found on our wiki. This page will be kept up-to-date as changes are made.


Cheers!

David and Avi

--
You received this message because you are subscribed to the Google Groups "meteor-talk" group.

Avital Oliver

unread,
Nov 13, 2013, 5:40:00 PM11/13/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
We have a new release on this track: template-engine-preview-5.

Changes from template-engine-preview-4:
* Fixed a bug related to {{#each}} on cursors (thanks David Glasser for finding and helping investigate)
* Fixed a bug on Internet Explorer related to dynamic element attributes
* Merged the Meteor 0.6.6.3 release.

As always, feedback is welcome.

Thanks,
David and Avital.

Jan Hansen

unread,
Nov 14, 2013, 6:56:58 AM11/14/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
Nice work!

Would it be possible to make a track that always pointed to the newest template-engine-preview?
I.e. I would run "meteor --release template-engine-preview" and get template-engine-preview-5 today, template-engine-preview-6 tomorrow? :-)

Jan

Nick R

unread,
Nov 15, 2013, 3:46:28 AM11/15/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
This looks like a great improvement.  The existence of "constant" and "persist" really worried me in the current code base.  These things may have been welcomed by people who are used to Backbone's manual templating system, but if you are accustomed to the advanced templating in AngularJS, Knockout, Ember, or Polymer, Meteor's templating appears pretty primitive in comparison.

That said, the fact that it still only supports Mustache is disappointing to me.  I find the scoping model in Mustache to be very difficult to get used to.  I think it would be more intuitive to follow the lead of Polymer or AngularJS, which provide a more classical way to reference values in templates.  Furthermore, these frameworks are prototypes for the emerging Web Components standard, so they likely indicate what the future of the web will look like.

I wish I could use AngularJS or Polymer with Meteor.  There are packages out there that attempt this, but Meteor has quickly broken compatibility with them.  I wish supporting these was a priority.

Btw, browsers now support a <template> tag.  Is it possible to emit this tag in meteor, or will meteor think you're making one of its mustache templates?

David Greenspan

unread,
Nov 15, 2013, 6:22:54 AM11/15/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
Meteor applications shouldn't use Chrome and Firefox's <template> tags, which are not very useful anyway.  They're basically just a way to send uncompiled templates to the client, as long as your uncompiled templates happen to look exactly like HTML.  Meteor compiles templates on the server and will support a range of template syntaxes.  Angular really bends over backwards to use the browser's HTML parser as the first pass of its compiler, and it prevents Angular from having nice control structures like "each," forcing it to have the "ng-repeat" attribute instead, for example.

I won't say we can't learn a couple things from Angular's component model, but I believe we're building something that will have a much wider appeal.

-- David



--
You received this message because you are subscribed to the Google Groups "meteor-talk" group.

Abigail Watson

unread,
Nov 15, 2013, 6:34:15 PM11/15/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
+1 for building something with a much wider appeal.  :)

As someone who came to Meteor from the Mongo and D3 world, with no preconceived notions about Node, I have to say that I found the Meteor approach to be extremely elegant and easy to use.  The Angular and Ember and Knockout approaches just feel clunky by comparison.  So lets all be cognizant of confirmation bias!  And lets not re-implement Angular.  Lets do something better!  (hint, hint, Famo.us....)

Dan Evans

unread,
Nov 17, 2013, 3:48:07 PM11/17/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
Really enjoying the new template engine. Thanks for all your work on this! Quick question though: It seems that "Template.myTemplate.rendered" is firing before the contents of myTemplate are actually rendered. Is this expected behavior in the new paradigm? If not, is anyone else seeing this behavior or is it just me?

Thanks again!

Dan Evans

unread,
Nov 17, 2013, 4:07:19 PM11/17/13
to meteo...@googlegroups.com
Just to follow up, I can't duplicate the issue on a new app, so it must be something in my app creating the issue (I have iron-router and other packages installed in the app where I'm seeing this). So... it's probably just me.


-Dan


--
You received this message because you are subscribed to a topic in the Google Groups "meteor-talk" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/meteor-talk/gHSSlyxifec/unsubscribe.
To unsubscribe from this group and all its topics, send an email to meteor-talk...@googlegroups.com.

David Greenspan

unread,
Nov 17, 2013, 6:11:49 PM11/17/13
to meteo...@googlegroups.com
Rendered fires sooner than it used to; in particular, it doesn't wait for the template to be in the document.

It's on our list to fix!

-- David

Dan Evans

unread,
Nov 17, 2013, 6:18:59 PM11/17/13
to meteo...@googlegroups.com
Oh ok, in that case I'll stop trying to track it down and just hack in a brief timeout for now. Thanks for the reply! :)


-Dan

Mitar

unread,
Nov 18, 2013, 10:10:09 AM11/18/13
to meteo...@googlegroups.com
Hi!

I agree. Why does Meteor not use getters and setters on JavaScript
objects to improve reactivity? This would be useful in general for
objects from the database where instead of having to limit fields in a
query to prevent too many reruns, Meteor could simply trace which
fields user access in the object returned from the database.


Mitar

On Thu, Oct 24, 2013 at 11:34 PM, Morten Henriksen <m...@gi2.dk> wrote:
> Almost forgot, theres a brief readme with a short example of what the code
> does: https://github.com/raix/reactive/blob/master/README.md
>
> --
> You received this message because you are subscribed to the Google Groups
> "meteor-talk" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to meteor-talk...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.



--
http://mitar.tnode.com/
https://twitter.com/mitar_m

David Greenspan

unread,
Nov 18, 2013, 10:48:09 AM11/18/13
to meteo...@googlegroups.com
The main reason we don't use getters and setters is IE 8 doesn't support them.

-- David

Jan K. Hansen

unread,
Nov 18, 2013, 11:07:03 AM11/18/13
to meteo...@googlegroups.com
You've probably had a long talk about it already, but...
Ditch it. No reason to drag around a nearly 5 year old browser. People
using it will be used to increasingly nonfunctional web anyway.
Help the world to get rid of it by not supporting it. You (core
developers) will be coding happier as well! :-)

Sorry to drag this OT...

Jan

2013/11/18 David Greenspan <da...@meteor.com>:

Dirk Porsche

unread,
Nov 18, 2013, 2:38:52 PM11/18/13
to meteo...@googlegroups.com
+1 for killing IE8 support.

Dan Evans

unread,
Nov 18, 2013, 11:44:09 PM11/18/13
to meteo...@googlegroups.com
I just saw read the conversation about rendered you had with Gadi earlier and I now understand it better. I should have read this thread more thoroughly before posting. Anyway, thanks again for your help!

-Dan

Matthew.forr

unread,
Nov 18, 2013, 11:44:34 PM11/18/13
to meteo...@googlegroups.com
Hi meteo...@googlegroups.com,

Thank you for contacting the pixelhacking Help Desk. We've received your request and will get back to you with a response as quickly as possible.

Cheers,

The pixelhacking Support Team

Eric Dobbertin

unread,
Nov 21, 2013, 8:09:37 PM11/21/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
I'm finally getting a chance to try out the new API. In trying to adapt the autoform package, there's a pattern I use, which I've used in other packages, too, that allowed a helper to render any HTML attributes without knowing what they are. Like this (simplified):

{{> content}}
<template name="autoForm">
  <form{{{atts}}}>
    {{> content}}
  </form>
</template>

Handlebars.registerHelper("autoForm", function(options) {
  return Template.autoForm.withData({ atts: objToAttributes(options.hash) });
});

var objToAttributes = function(obj) {
  var a = "";
  _.each(obj, function(value, key) {
    a += ' ' + key + '="' + value + '"';
  });
  return a;
};

The goal being that all the helper's keyword arguments (after removing any we are expecting) are transferred to the rendered HTML element's attributes. What is the best way to achieve this with the new API?

Maxime Quandalle

unread,
Nov 21, 2013, 10:49:36 PM11/21/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
Hi Eric,

According to the spacebars doc [1], your template helper can return an object of key/values that will be used for the attributes of the HTML element.
I never test it though.

Eric Dobbertin

unread,
Nov 21, 2013, 11:58:22 PM11/21/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
Maxime, that is helpful, but...
  • The docs are apparently outdated. There was a commit last week that changed it to double-stash and removed the ability to pass a string, both of which make sense to me. Readme should be updated.
  • Also, it doesn't work. I get a "Expected single HTML attribute name, found: '[object Object]'" error when passing an object with a couple valid properties with string values in the context.

NAVEEN BHRAMAKAR

unread,
Nov 22, 2013, 4:30:14 AM11/22/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
Why not use angular as a templating engine ? Why to reinvent the wheel, with a new templating engine ? 
Thoughts ??

Thomas Haferlach

unread,
Nov 22, 2013, 8:43:23 AM11/22/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
any updates on when it will be possible to use block helpers like {{#if}} inside of attribute values?

this is the only thing keeping me from updating to the new engine since i use a lot of constructs like:

<div class="{{#if isSelected}} large {{/if}}">...

David Greenspan

unread,
Nov 22, 2013, 12:24:51 PM11/22/13
to meteo...@googlegroups.com
Attribute dictionaries in <div {{attrs}}> and block helpers in attributes are coming!  Stay tuned.

-- David

Robert Dickert

unread,
Nov 22, 2013, 12:36:18 PM11/22/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
Thought I'd look up the change Eric Dobbertin came across. Posting the commit message here for anyone who's curious. Source(dgreensp)

don't use triple stache for HTML attrs in examples

This syntax has a bug where it relies on having html5-tokenizer on the client, code which was written for the server (and uses Function.bind, defineGetter, etc.).

The plan is to deprecate/remove this syntax anyway, i.e. not allow
you to say `<x {{{attrs}}}>` and then have `attrs` evaluate to a string like
'key1="value1" key2="value2"' at runtime.  Constructing these strings is error-prone and likely to be insecure.

Instead, you'll have your choice of double-stache in an attribute value, with or without quotes (`<a b={{c}}>`, or `<a b="{{c}} {{d}}"`, or even `<a b={{c}}-{{d}}>`), or double-stache at the top level of a tag, as in `<a {{b}}>`, in which case `b` must be either a dictionary of attribute names and values or a string containing at most a single attribute name (e.g. "selected" or "").

Gadi Cohen

unread,
Nov 23, 2013, 5:23:09 AM11/23/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
Super cool and super excited :)

Eric Dobbertin

unread,
Nov 23, 2013, 11:04:51 AM11/23/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
Glad to hear the attribute fixes are coming! I found another thing kind of strange (in preview-5), but maybe I just don't understand how things are supposed to work.

HTML

<body>
  {{printPositional "Hello World!"}}
  {{print text="Hello World!"}}
  {{#with info}}
  {{text}}
  {{printPositional text}}
  {{print text=text}}
  {{print2 text=text}}
  {{/with}}
</body>

JS

  UI.body.print = function (options) {
    return options.text;
  };
  UI.body.print2 = function (options) {
    return options.text();
  };
  UI.body.printPositional = function (text) {
    return text;
  };
  UI.body.info = function () {
    return {text: "Hello World!"};
  };

At the end of the with block, I don't understand why print2 works but not print. I would expect "text" to be the value of the property, which is a string, but instead it's a function that evaluates to the string. It works as I expect when passed positionally, but not when it's the value of a keyword argument.

Pieter Soudan

unread,
Nov 28, 2013, 10:40:04 AM11/28/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
Possible bug found using collection transforms against template-engine-preview-5

When using a transform function returning custom class instances for every collection item, you loose this transformed state when the collections is manipulated.
- When the collection's sorting is changed, every item is updated and they all loose their transformed state.
- When the filtering criteria of the collection result set is changed, only the newly added items have a transformed state. All previously rendered items, loose their transformed state but keep their rendered state in DOM.
- When a new item is inserted, this item has a transformed state and all other items are unaffected.

I set up an app to demonstrate these cases:

Hope this helps.

Sacha Fournier

unread,
Nov 29, 2013, 6:12:36 PM11/29/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
Not sure if it's a bug, when having a template with:

<textarea>{{value}}</textarea>

I get a rendered textarea with a <script....> tag in it.

Working fine with other tags (<input type="text" value="{{value}}"...) for instance. 

Sacha

Slava Kim

unread,
Nov 29, 2013, 10:31:14 PM11/29/13
to meteo...@googlegroups.com, meteo...@googlegroups.com

Mitar

unread,
Nov 29, 2013, 11:10:23 PM11/29/13
to meteo...@googlegroups.com
Hi!

But on the server side they could still be supported? For example,
when you access userId in publish function, Meteor could remember that
and restart publish then. If you do not access userId, then it would
not restart publish when user logs in our out.


Mitar

kvd...@gmail.com

unread,
Dec 6, 2013, 7:24:16 AM12/6/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
I've added a template (Bootstrap modal) to the DOM with

UI.insert(UI.render(Template.modal), document.body);

Then I intialize the modal on rendered with

Template.modal.rendered = function() {
  var self = this;

  $(this.firstNode).modal().on('hidden.bs.modal', function () {
    // Destroy template, howto?
  });
}

Then, I would like to take the template off the screen when the modal is closed (and not just remove the node from the DOM). How do I do that?

Thanks,
Koen

Silly Clown

unread,
Dec 6, 2013, 8:22:48 AM12/6/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
Maybe keep a stage template in your layout. 

<div class="modalStage">
   {{#if showModal }}
    {{> modalTemplate }}
   {{/if}}
</div>

kvd...@gmail.com

unread,
Dec 7, 2013, 3:44:19 AM12/7/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
template.__component__.dom.remove()

Or is it bad practice to use __component__?

Morten Henriksen

unread,
Dec 9, 2013, 3:25:48 AM12/9/13
to meteo...@googlegroups.com, meteo...@googlegroups.com

Not sure how this works in the new UI:

Would be nice if we could simply invoke object functions directly as simple helpers without having to declare.
Eg.:

{{#each imagefiles}}
  <a href="{{downloadUrl}}" download>Click here to download</a>
  Name: {{name}}
  Size: {{size}}
{{/each}}

Where downloadUrl is a function mounted on each imagefiles item - could potentially take arguments.


Den søndag den 8. december 2013 22.02.33 UTC+1 skrev Max Harris:
What do I have to do to get fields to work? (This is from Devshop 6) https://www.youtube.com/watch?v=pGQ-ax5cFnk#t=817

I am using the shark branch right now, and UI.Component.current is undefined.

This feature solves the most important issue we have with Meteor right now.

Thanks,

- Max

On Wednesday, November 13, 2013 2:40:00 PM UTC-8, Avital Oliver wrote:
We have a new release on this track: template-engine-preview-5.

Changes from template-engine-preview-4:
* Fixed a bug related to {{#each}} on cursors (thanks David Glasser for finding and helping investigate)
* Fixed a bug on Internet Explorer related to dynamic element attributes
* Merged the Meteor 0.6.6.3 release.

As always, feedback is welcome.

Thanks,
David and Avital.
On Fri, Nov 8, 2013 at 3:58 PM, Avital Oliver <avi...@meteor.com> wrote:
Hi fellow cutting-edge experimenters!

We've just released `template-engine-preview-4` in which SELECT tags work. We've also made `{{#with falseyValue}}` behave like it does on the released version of Meteor. The wiki page has been updated.

Try it out and let us know of any problems!

Thanks,
Avital.
On Mon, Oct 14, 2013 at 9:41 PM, David Greenspan <da...@meteor.com> wrote:
Good evening!

We are very excited to announce the first preview release for the new templating engine. This preview release contains work we've been developing on a branch, which replaces machinery such as Spark and Liverange but supports roughly the same template API as before. The new engine has simpler, easier-to-understand behavior with respect to the DOM; you don't have to use `{{#constant}}` and `preserve` directives or guard against multiple "rendered" callbacks.  jQuery plugins work well with Meteor templates. Some API changes will require porting packages and apps, but we've tried to keep the new engine as backwards compatible as possible.

This work is absolutely not yet ready for use in production apps.  In fact, it's much more unfinished than usual for code that we're soliciting feedback on.  However, there's been so much interest and excitement about Meteor UI that we think our hardcore users might be willing to help bang on a buggy version.  We're releasing this early to get feedback about the new API, to learn about bugs that can be reproduced in small apps, and to give package and app authors some time to prepare for the upcoming release. Some packages, most notably ones generating forms or implementing routing, will have to be ported first. We'll be releasing additional preview releases as we get further down the path on the track for Meteor 0.7.0.

Details about the changes and how to run the code can be found on our wiki. This page will be kept up-to-date as changes are made.


Cheers!

David and Avi

Piotr Osiński

unread,
Dec 10, 2013, 8:26:48 AM12/10/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
Hi, I wanted to share my concern about new engine's performance. Given code from my repo https://github.com/happyfox13/meteor-shark-engine-test I ran this simple app with version 0.6.6.3 and new UI engine release 5. The downgrade in performance was huge! From 290 ms to 1250ms (new engine) in rendering simple template of 300 documents with one "join". I wanted to ask, if somebody can look at my code and tell me if the performance will be better with the final release or new engine needs some special syntax to show it's true power?

Cheers, Peter

Torsten Blindert

unread,
Dec 12, 2013, 11:09:43 AM12/12/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
Hey, am I missing something fundamental here or is it a bug that the {{#each}} view helper still runs after the template is destroyed?

Avital Oliver

unread,
Dec 12, 2013, 12:28:19 PM12/12/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
Hi Torsten. That is indeed a bug, and has been fixed on the shark branch. Expect a new preview release fairly soon.


On Thu, Dec 12, 2013 at 8:09 AM, Torsten Blindert <torsten....@googlemail.com> wrote:
Hey, am I missing something fundamental here or is it a bug that the {{#each}} view helper still runs after the template is destroyed?

--
You received this message because you are subscribed to the Google Groups "meteor-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to meteor-core...@googlegroups.com.
To post to this group, send email to meteo...@googlegroups.com.
Visit this group at http://groups.google.com/group/meteor-core.

Chris Mather

unread,
Dec 12, 2013, 10:18:24 PM12/12/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
I wasn't sure if I should start a new thread for my question/thought but here it goes :-). 
  • It would be nice to search the global namespace in the Spacebars lookup chain.
  • I often have functions that I'd like to use from several places (e.g. isUserAdmin).
  • So I end up creating an App namespace, throwing the functions in there and then creating Handlebars helpers to make them available to templates.
  • It would be nice if instead I could write:
App = {
  isUserAdmin: function () {
    return true;
  }
};

<template name="...">
  {{#if App.isUserAdmin}}
  {{/if}}
</template>

Morten Henriksen

unread,
Dec 13, 2013, 3:39:05 AM12/13/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
Agree with Chris, it would be nice to be able to registrate global objects in template scope,
Eg.:
  Helpers.addScope('Session', Session);
  Helpers.addScope('Meteor', Meteor);
This is pretty useful eg.:
Read my session: {{Session.get 'mySession'}}

Is my session equal to 4?: {{Session.equals 'mySession' 4}}

Does this helper render??: {{console.log 'Why would you ever add console to the global helper scope?'}}

What user id do I got: {{Meteor.userId}}

What's the connection status?: {{Meteor.status.status}}

Hmm, I am client right? {{Meteor.isClient}}
{{Meteor.status.status}} Looks a bit off why I did FR https://groups.google.com/forum/#!topic/meteor-core/hdI4FfZktuU

Avital Oliver

unread,
Dec 13, 2013, 1:41:48 PM12/13/13
to meteo...@googlegroups.com, meteo...@googlegroups.com
Chris, if you also call `Handlebars.registerHelper('App', App)` this will work. Does that resolve your concern?

It is loading more messages.
0 new messages