Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

if/else/each keywords #55

Closed
devinrhode2 opened this Issue Sep 18, 2012 · 18 comments

Comments

Projects
None yet
4 participants

A form of the if keyword is being requested here: #22
And similarly a form of the each keyword here: #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.

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 Oct 20, 2012

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 Oct 20, 2012

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 #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.

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

wesen commented Oct 31, 2012

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 Oct 31, 2012

@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 Oct 31, 2012

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 Oct 31, 2012

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

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 Nov 1, 2012

@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 :-)

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 Nov 1, 2012

@devinrhode2 I'd be so happy :-)

groue commented Nov 2, 2012

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 :-)

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 Nov 2, 2012

Oops :-) My mistake :-)

groue commented Nov 2, 2012

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

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:

  • Tests for "if…else...end" : {{#foo}}…{{^foo}}…{{/foo}}groue/GRMustache@6c359ee

  • Tests for "unless…else...end" : {{^foo}}…{{#foo}}…{{/foo}}groue/GRMustache@35125ca


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

urzds commented Jan 28, 2017 edited

I also would like to see an explicit "if" syntax, like @wesen mentioned in #55 (comment).

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.

urzds added a commit to urzds/lustache that referenced this issue Jan 28, 2017

Support explicit conditional blocks
Explicit conditional blocks are e.g. necessary to support introducing the
 expansion of a list with an optional header, like in the following example:

```mustache
{{?products}}
Product names:
  {{#products}}
  - {{name}}
  {{/products}}
{{/products}}
{{^products}}
No products
{{/products}}
```

See-Also: mustache/spec#22
See-Also: mustache/spec#55 (comment)

urzds added a commit to urzds/lustache that referenced this issue Jan 28, 2017

Support explicit conditional blocks
Explicit conditional blocks are e.g. necessary to support introducing the
 expansion of a list with an optional header, like in the following example:

```mustache
{{?products}}
Product names:
  {{#products}}
  - {{name}}
  {{/products}}
{{/products}}
{{^products}}
No products
{{/products}}
```

I did not include tests, because their data is included in the corresponding
 pull request to the Mustache spec.

See-Also: mustache/spec#22
See-Also: mustache/spec#55 (comment)

@urzds urzds referenced this issue in Olivine-Labs/lustache Jan 28, 2017

Open

Support explicit conditional blocks #25

urzds added a commit to urzds/lustache that referenced this issue Feb 1, 2017

Support explicit conditional blocks
Explicit conditional blocks are e.g. necessary to support introducing the
 expansion of a list with an optional header, like in the following example:

```mustache
{{?products}}
Product names:
  {{#products}}
  - {{name}}
  {{/products}}
{{/products}}
{{^products}}
No products
{{/products}}
```

I did not include tests, because their data is included in the corresponding
 pull request to the Mustache spec.

See-Also: mustache/spec#22
See-Also: mustache/spec#55 (comment)

urzds added a commit to urzds/lustache that referenced this issue Feb 1, 2017

Support explicit conditional blocks
Explicit conditional blocks are e.g. necessary to support introducing the
 expansion of a list with an optional header, like in the following example:

```mustache
{{?products}}
Product names:
  {{#products}}
  - {{name}}
  {{/products}}
{{/products}}
{{^products}}
No products
{{/products}}
```

I did not include tests, because their data is included in the corresponding
 pull request to the Mustache spec.

See-Also: mustache/spec#22
See-Also: mustache/spec#55 (comment)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment