mustache / spec

The Mustache spec.
MIT License
368 stars 71 forks source link

if/else/each keywords #55

Closed devinrhode2 closed 12 years ago

devinrhode2 commented 12 years ago

A form of the if keyword is being requested here: https://github.com/mustache/spec/pull/22 And similarly a form of the each keyword here: https://github.com/mustache/spec/pull/23 @janl made a request for an easier else too: http://writing.jan.io/mustache-2.0.html

I think obscuring the meaning of something that actually means each down to a one symbol: , is stupid and not the hard to read and learn.

@wesen, is there any reason you want short symbols instead of real keywords?

This should be part of Mustache 2.0.

Handlebars also has with and unless keywords, which we could consider.

devinrhode2 commented 12 years ago

I think I'd rather see a simple converter that adds and removes these keywords for compatibility. Unless everyone wants the keywords that we can cement it in the spec. @groue, thoughts?

groue commented 12 years ago

Yep, @devinrhode2. I always have thoughts :-)

I do not see the point of #22 and #23. I don't see any problem with versatile boolean/iteration/scope sections that should be fixed, and certainly not the "efficiency" problem raised by @wesen. It's not as if versatile sections branching was costly. And if a spec is convenient, it is convenient for the end-user, not for the implementor. There is no room for whiny implementors. (I don't want to sound harsh, I just say the efficiency argument does not stand).

About the {{#foo}}...{{^foo}}...{{/foo}} "else" construct of @janl: this is again a convenience feature, but for the end user, this time. So it deserves a look. It is actually interesting, but it's not backward-compatible with Mustache 1 (which would complain abot the missing closing tag for the first {{#foo}}). A construct like {{#foo}}...{{^}}...{{/}} could be implemented without breaking compatibility. Some Mustache implementations already accept the empty closing tag.

About "keywords". Keywords are evil. Keywords are evil, because the more keywords has a language, the more the language is bloated with features that could not be implemented with the user's own code. This means that the language is not extensible, not versatile, not hackable, not handy at all, and finally, a mere toy. Need feature X? You have to wait for the next release of the language, if it ever happens. Seriously.

So keywords are clearly the wrong direction. Mustache already have a few ones: #, >, ^, /. We should avoid adding more keywords, and instead make Mustache more versatile.

Handlebars' with, each, unless are not keywords. They are built-in helpers, that use the public Handlebars API. Handlebars users can write their own helpers with the same API, and extend the language. See https://gist.github.com/1048968 for a telling example.

Mustache also needs versatility and extensibility. Mustache does not need feature-bloat and keywords. The work done so far on lambda sections, lambda variables, and filters go in the right direction: they allow the user to inject his code right into the Mustache engine, and to extend it.

Now let's get very precise.

with is already implemented: {{#object}}...{{/object}} does exactly what with is supposed to do.

each is already implemented: {{#items}}...{{/items}} does exactly what each is supposed to do.

unless is already implemented: {{^condition}}...{{/condition}} does exactly what unless is supposed to do.

Etc. Do people know what they talk about when they ask for a "missing" feature?

GRMustache has a few sample codes that are less trivial, and demonstrates that a shipped and Mustache-1-compatible implementation can empower the user without adding any keyword. See for instance:

groue commented 12 years ago

Ho, and if one likes the Handlebars' each_with_index helper of https://gist.github.com/1048968, do not miss https://github.com/groue/GRMustache/blob/master/Guides/sample_code/indexes.md.

Yes, it's possible for Mustache to render array indexes as well.

It is a little more complex than in Handlebars, because Handlebars is Javascript-only, and does not care about being ported in other languages. Mustache does care about being portable in other languages: it is its main asset. And my own care, as a Mustache implementor, is thus to provide portable and robust tools. GRMustache has added two extensions to Mustache that, presumably, are portable in other languages: filters and proxies. Together, a Mustache filter can perform just as a Handlebars helper does (see sample codes linked above).

Filters are discussed at https://github.com/mustache/spec/issues/41. Proxies are a Mustache API tool that do not have any associated syntax: they are objects that allow the developer to "wrap" an object in another, the proxy, that can extend the abilities of the wrapped object (for example, by adding the index key).

I believe this is how Mustache should be enhanced: by providing a tiny set of powerful tools. Not by bloating the syntax with short-sighted features.

devinrhode2 commented 12 years ago

Legit. I think the best approach is to make a little converter if someone (like me) wants to have keywords for readability.

wesen commented 12 years ago

the problem with {{#}} for both iteration and conditional is that there is no way to distinguish between the two. if i just want to test for presence, i have to introduce another variable, for example

{{#hasProducts}}
Product names:
{{#products}}{{name}}{{/products}}
{{/hasProducts}}
{{^hasProducts}}
No products.
{{/hasProducts}}
groue commented 12 years ago

@wesen : yes, this is an issue. But as soon as you introduce filters, the problem vanishes.

{{#present?(products)}}
    Product names:
    {{#products}}{{name}}{{/products}}
{{/}}
{{^present?(products)}}
    No products.
{{/}}

I much prefer fostering filters than a syntax change (see my rant against keywords above).

wesen commented 12 years ago

The fact I like about having only keywords, and in this case this is really more of a convenience kind of thing, is that I can easily use the same templates on the server (with my php compiler Proust), and on the client with janl's implementation. Making something like handlebars or anything with more keywords portable is a bit more work I guess. Anyway this is old, I'm using the approach below for quite a while now, even though my engine supports both.

On Oct 31, 2012, at 8:25 AM, Gwendal Roué notifications@github.com wrote:

@wesen : yes, this is an issue. But as soon as you introduce filters, the problem vanishes.

{{#present?(products)}} Product names: {{#products}}{{name}}{{/products}} {{/}} {{^present?(products)}} No products. {{/}} I much prefer fostering filters than a syntax change (see my rant against keywords above).

— Reply to this email directly or view it on GitHub.

groue commented 12 years ago

I 100% support with you on the interoperability theme. Foster a standard library of filters, similar to the one Handlebars has.

And please read again aboe the distinction between keywords and built-in helpers. Their main difference is the fact that keywords are dead-ends, when built-in helpers are just a convenience that prevents the user to reinvent the wheel. I want Mustache to allow extensions like https://gist.github.com/1048968. And it can: https://github.com/groue/GRMustache/blob/master/Guides/sample_code/indexes.md

devinrhode2 commented 12 years ago

Ok, so I think I should clarify: I only desire if/else and each keywords for readability. I want accessibility for designers.

On Wed, Oct 31, 2012 at 5:18 AM, Gwendal Roué notifications@github.comwrote:

I 100% support with you on the interoperability theme. Foster a standard library of filters, similar to the one Handlebars has.

And please read again aboe the distinction between keywords and built-in helpers. Their main difference is the fact that keywords are dead-ends, when built-in helpers are just a convenience that prevents the user to reinvent the wheel. I want Mustache to allow extensions like https://gist.github.com/1048968. And it can: https://github.com/groue/GRMustache/blob/master/Guides/sample_code/indexes.md

— Reply to this email directly or view it on GitHubhttps://github.com/mustache/spec/issues/55#issuecomment-9942535.

groue commented 12 years ago

@devinrhode2 Yeah, if/else would be handy. When I read my initial reaction:

About the {{#foo}}...{{^foo}}...{{/foo}} "else" construct of @janl: [...] it's not backward-compatible with Mustache 1 (which would complain abot the missing closing tag for the first {{#foo}}).

It is true that it's not strictly compatible with Mustache-1, since the introduction of the feature would turn an ill-formed template into a valid template. But I was stupid saying that this prevent the introduction of the feature. On the contrary, nobody would be hurt since nobody keeps ill-formed templates in their sources. So, OK for the {{#foo}}...{{^foo}}...{{/foo}} construct :-)

devinrhode2 commented 12 years ago

Damn I didn't realize this isn't specc'd...

@groue Let's get this and the filters thing and layouts done... this weekend? (My skype is my same username, we could also do a public G+ hangout)

-Devin http://zerply.com/DevinRhode2 http://zerply.com/devinrhode2

On Thu, Nov 1, 2012 at 12:36 AM, Gwendal Roué notifications@github.comwrote:

@devinrhode2 https://github.com/devinrhode2 Yeah, if/else would be handy. When I read my initial reaction:

About the {{#foo}}...{{^foo}}...{{/foo}} "else" construct of @janlhttps://github.com/janl: [...] it's not backward-compatible with Mustache 1 (which would complain abot the missing closing tag for the first {{#foo}}).

It is true that it's not strictly compatible with Mustache-1, since the introduction of the feature would turn an ill-formed template into a valid template. But I was stupid saying that this prevent the introduction of the feature. On the contrary, nobody would be hurt since nobody keeps ill-formed templates in their sources. So, OK for the {{#foo}}...{{^foo}}...{{/foo}} construct :-)

— Reply to this email directly or view it on GitHubhttps://github.com/mustache/spec/issues/55#issuecomment-9972890.

groue commented 12 years ago

@devinrhode2 I'd be so happy :-)

groue commented 12 years ago

Devin, I almost forgot: I won't be available this weekend.

Do you still wanna implement the {{#foo}}…{{^foo}}…{{/foo}} on your fork of GRMustache? If so, here is what I would do. Please don't feel overwhelmed: we can achieve the full target in a common effort :-)

Comprehensive support would allow those syntaxes as well:

Tests for parsing errors would enter https://github.com/groue/GRMustache/blob/master/src/tests/Public/v6.0/GRMustacheParsingErrorsTest.m

devinrhode2 commented 12 years ago

Probably not, never done Obj-C before, and there's other js things I'd like to work on

On Friday, November 2, 2012, Gwendal Roué wrote:

Devin, I almost forgot: I won't be available this weekend.

Do you still wanna implement the {{#foo}}…{{^foo}}…{{/foo}} on your fork of GRMustache? If so, here is what I would do. Please don't feel overwhelmed: we can achieve the full target in a common effort :-)

Comprehensive support would allow those syntaxes as well:

  • {{#foo}}…{{^}}…{{/}} (GRMustache already accepts empty closing tags, so empty else tags should be OK as well)
  • {{#foo}}…{{^}}…{{/foo}}
  • {{^foo}}…{{#foo}}…{{/foo}} (unless … else … end)
  • {{^foo}}…{{#}}…{{/}}
  • {{^foo}}…{{#}}…{{/foo}}

Tests for parsing errors would enter https://github.com/groue/GRMustache/blob/master/src/tests/Public/v6.0/GRMustacheParsingErrorsTest.m:

  • {{#foo}}…{{^foo}}…{{/bar}}
  • {{#foo}}…{{^}}…{{/bar}}
  • All ill-formed templates we could think about :-)

    — Reply to this email directly or view it on GitHubhttps://github.com/mustache/spec/issues/55#issuecomment-10006634.

-Devin http://zerply.com/DevinRhode2 http://zerply.com/devinrhode2

groue commented 12 years ago

Oops :-) My mistake :-)

groue commented 12 years ago

@devinrhode2 : "Else" clauses are implemented in GRMustache. You'll find the tests in those two commits:

devinrhode2 commented 12 years ago

Nice!

-Devin http://zerply.com/DevinRhode2 http://zerply.com/devinrhode2

On Fri, Nov 2, 2012 at 12:33 PM, Gwendal Roué notifications@github.comwrote:

@devinrhode2 https://github.com/devinrhode2 : "Else" clauses are implemented in GRMustache. You'll find the tests in those two commits:

ghost commented 7 years ago

I also would like to see an explicit "if" syntax, like @wesen mentioned in https://github.com/mustache/spec/issues/55#issuecomment-9936333.

I would enhance the syntax like so:

{{?products}}
Product names:
{{#products}}{{name}}{{/products}}
{{^products}}
No products.
{{/products}}

P.S. I just looked into #22 and see this syntax is exactly what was proposed there.

rekhapriyan commented 4 years ago

Hi I have the below mustache script for my slack notification message.

In this alerts are generating for same error for the same Store ID. I am trying to give some condition to filter only one store id with the same error.

Error Output now

Need to display only one error out of these three error. Any suggestions on the mustache script to be modified to?