mquandalle / meteor-jade

The Jade template engine for Meteor/Blaze
http://atmospherejs.com/mquandalle/jade
MIT License
307 stars 39 forks source link

Inline JavaScript expressions #1

Closed mquandalle closed 6 years ago

mquandalle commented 10 years ago

It would be useful to be able to define some kind of "anonymous helpers" like this:

if player.score > 10
  p Well done!

As far as I know, it's not yet possible to define this kind of things in the Spacebars abstract tree. So maybe it's more a Spacebars feature? @dgreensp?

lfender6445 commented 10 years ago

this would be excellent :+1:

DenisGorbachev commented 10 years ago

+1

trollfred commented 9 years ago

would be awesome

levino commented 9 years ago

Yeah, that would be great stuff!

igregson commented 9 years ago

yes please :)

antonamurskiy commented 9 years ago

can this happen please

mquandalle commented 9 years ago

I would have expected the blaze runtime and the spacebars compiler to bring this functionality earlier. Since it doesn't seem to be a priority for the meteor core team (which I can understand) I'm willing to provide a mid-term solution.

I've been always careful while designing this package to not add some runtime overhead, all operations are done during the compilation and the content sent to the client is then exactly the same as if you used spacebars (and this is how this package is effectively tested).

But I'm willing to do an exception for this feature. I would like to add a weak dependency on the handlebar-helpers by @raix. I'm particularly interested in the $eq, $neq, $lt, $gt, $lte, $gte, $and, $or, and $not helpers. For all of these what I could do is provide syntactic sugar so writing

if player.score > 10

is equivalent to

if $gt player.score 10

This feature would be provided only to raix:handlebar-helpers users. Thoughts?

laurentpayot commented 9 years ago

That would be nice, if temporary. Also it’s a pity not to be able to use object mapping to true or false for class names such as li(class={checked: checked, private: private}). So handlebar helpers such as {{isChecked a b}} could also be helpful but wouldn’t work anyway for an arbitrary class name such as "private". Just my thoughts...

Taik commented 9 years ago

+1. Any updates on this?

filipstachura commented 9 years ago

Anything?

Pickachu commented 9 years ago

:+1: Go go go people!

programaths commented 9 years ago

Indeed, that seems to be a blocker.

I am trying to do something like this :

//Content of formControl.tpl.jade
.form-group
        label.park-form-label= label
        .park-form-field
        if type=="area"
            textarea.form-control(name=name)
        else
            input.form-control(type=type,name=name)

and it won't compile. This is a case where I can't put multiples variables like "isTextarea","isSelect", ...

On the call site it is would be :

+formControl(label="Name" name="name" type="text")
+formControl(label="Description" name="name" type="area")

This is a use case which could show that it is important.

The alternative would be to duplicate code to have one template per type of control!

levino commented 9 years ago

@programaths No. You can just write a helper for the template and call it "isTypeEqualArea". In it you evaluate your type variable (this.type or just pass it the type varbiable).

michelalbers commented 9 years ago

+1 would be SOO nice

darrynten commented 9 years ago

The fact that this is still not a thing is mindblowing and makes this package pretty useless IMHO.

mquandalle commented 9 years ago

I've spent a few hours trying to implement this functionality but I ran into at least two high-level non-trivial obstacles:

  1. meteor-jade targets the meteor-blaze runtime, and that runtime currently doesn't support inline JavaScript expressions. Along other problems, this makes things difficult for the compilation step because we use the same AST than spacebars (which is why meteor-jade has the same feature set than spacebars, it's just a more concise syntax), and that AST doesn't have the necessary types to model and compile JavaScript expressions;
  2. You need to either break all the existing meteor-jade templates, or to create a brand new DSL to support both old and new expressions (better to avoid that). For instance function calls are currently written {{fun arg1 arg2}}, so we either have to create a coffeescript-ish DSL that support both the previous syntax and the new one or to break the existing code. Breaking the existing code is not as easy as it sounds because we currently use things like ../val to read a value from a upper context, but there is no way to express this idea in JavaScript — that's because scopes works completely differently in it. And again we could create a DSL that would accept things like ../val[@index] but that seems unreasonable (if you are not convinced I can find crazier examples).

@darrynten if this package is useless to you, use something else. The default in meteor is Spacebars but as explained above it has the same limitations than meteor-jade, and it won't help you with the issue of inline expressions. Otherwise you can try React+JSX which have a strong support in the JS community and a complete JS expressions support. As downsides it is also less integrated with the rest of the meteor stack (especially with tracker) and doesn't have anything like a concise {haml,jade}-like syntax (if you like that).

niallobrien commented 8 years ago

Would any of the new APIs in Meteor 1.2 help here at all?

fakepilot commented 8 years ago

Found this page, when searching for an Jade equivalent to Handlebars inline "if's", example: li(class="{{#if checked}}checked{{/if}}")

But then I guess there isn't? Still works thought, so no biggy.

pixelass commented 8 years ago

I think the problem is something different. Handlebars is not imperative like Jade. It is a declarative language.

What you are trying to do is mix apples with oranges, or better yet make apples taste like oranges.

In declarative programming we can use helpers or built in functions to do similar things but we need to keep in mind that we are limited.

For those who do not understand what the difference is: http://latentflip.com/imperative-vs-declarative/

It is the same issue if you argue about Less.js vs. Sass. Less does not have native loops or other functions. We can use tricks to do this though. Please note that I myself have used these tricks but I am not recommending this. If you disguise a declarative language with an imperative syntax it does not mean you will have access to imperative programming

Look at these two libs I wrote:

they try to add imperative behavior to Less.js.

AlbinoGeek commented 8 years ago

@pixelass I agree with you, and I would be against (I would in fact probably write my guides to strongly recommend against) the use of the inline code where-ever possible, and to not treat it as any more than a "fancy data selector".

The main points where I would have people use this feature, are to replace class selectors ("selected", "deleted", etc) and other logic that currently can't even be solved with &dyn (unless you use coffee-jade or another similar fork). It would be another step just like Unwrapped Templates that allows people to code more efficiently, without having to make many files.

dr-dimitru commented 8 years ago

Hi @mquandalle I've implemented (but not anonymous) helpers which can solve most of use-cases, we can try to merge for Jade sugar, see templatehelpers package

nscarcella commented 8 years ago

+1 Is anyone currently working on this?