Would people be interested if I added {{}} delimeters?

242 views
Skip to first unread message

Bernie

unread,
Apr 21, 2012, 1:40:05 PM4/21/12
to Haml
Just want to make sure I don't use time that could be spent somewhere
else. Here's the idea:

Many JS templating languages appear to use the "{{ some_content }}"
strategy for delimiting content, and Mustache and Handlebars appear to
be the most popular among those lang's.

Since Haml appears to not have an easy way to add custom delimeters
(parsing occurs all the way in the parser.rb file), would it make
sense to add these "{{" delimeters directly to haml?

The end result would be something like this:

%table
%tbody
{{# each MyApp.MyArray
%tr
%td {{ someValue }}
%tfoot
%tr
%td Some footer content

Thoughts, concerns?

Duncan Beevers

unread,
Apr 22, 2012, 1:10:49 PM4/22/12
to ha...@googlegroups.com
There have been a number of approaches to help make it simpler to use
haml for client-side templates. One popular implementation is hamlbars
https://github.com/jamesotron/hamlbars which provides some helper
methods, and my own academic experiments in extending haml in a
similar fashion here: https://github.com/duncanbeevers/haml-ejs

That said, many client-side templating languages use different or
customizable delimiters, and support different subsets of javascript
within the templates, from full-js-interpretation all the way down to
only-top-level-properties-of-a-single-data-object, and extending haml
to deal with all of these is pretty much guaranteed to only serve a
subset of the needs programmers will have down the line.

haml itself is already a member of the school of templating languages
that provide access to the full functionality of the ruby interpreter
within the template. Adding extra delimiters means a human looking
over a templates needs to mentally parse two to three languages just
to figure out what's going on.

Is haml the way forward? Should it be re-plumbed to make adding custom
delimiters part of its public API? Should it embrace generation of
client-side templates and include first-class support for this new
family of consumers?

I don't know. So far, using haml for these purposes has been a mixed
bag. The results have been great, but the friction on the way has not
been pleasant.

On Sat, Apr 21, 2012 at 12:40 PM, Bernie <bte...@gmail.com> wrote:
> Just want to make sure I don't use time that could be spent somewheret


> else. Here's the idea:
>
> Many JS templating languages appear to use the "{{ some_content }}"
> strategy for delimiting content, and Mustache and Handlebars appear to
> be the most popular among those lang's.
>
> Since Haml appears to not have an easy way to add custom delimeters
> (parsing occurs all the way in the parser.rb file), would it make
> sense to add these "{{" delimeters directly to haml?
>
> The end result would be something like this:
>
> %table
>  %tbody
>    {{# each MyApp.MyArray
>      %tr
>        %td {{ someValue }}
>  %tfoot
>    %tr
>      %td Some footer content
>
> Thoughts, concerns?
>

> --
> You received this message because you are subscribed to the Google Groups "Haml" group.
> To post to this group, send email to ha...@googlegroups.com.
> To unsubscribe from this group, send email to haml+uns...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/haml?hl=en.
>

Bernie

unread,
Apr 22, 2012, 3:17:33 PM4/22/12
to ha...@googlegroups.com
Thanks for the thoughtful reply, Duncan. You had a lot of questions in there, and I'll try to answer most of them. We, the developers at Wildfire Interactive have discussed most of those concerns, and I think you and I are on the same page.

One of the main goals of adding JS delimiter support is that we would be able to keep the semantic significance of indentation. Hamlbars has helpers, but block expressions such as 'each' cannot take nested haml blocks. This may be an implementation detail with Hamlbars that could be amended, but it's just not there yet, and we think it's an important missing feature.

I like the implementation that you suggested whereby using a '^' character disassociates the javascriptiness of other delimiters (such as {{ or {%) in a similar fashion to that of the '%' character with open angle brackets. Having said that, I'm not quite sure where that fits in the scheme of things because I am not TOO familiar with ejs, but it looks so similar to erb that I'm afraid people will be confused by the output, whereas some of the other delimiters out there look javascripty by their very nature (curly braces == javascript ?).

As far as humans having to parse through 3 different languages...keep in mind that no one is obligated to use these delimiters, just as much as no one is obligated to use the Textile or Markdown filters. This is just a tool in the belt that could make writing JavaScript templates as easy as writing haml/ruby templates.

If anyone else has any input, I think this may turn out to be an important topic,...please chime in :-)

Cheers,
Bernie



On Sunday, April 22, 2012 10:10:49 AM UTC-7, Duncan Beevers wrote:
There have been a number of approaches to help make it simpler to use
haml for client-side templates. One popular implementation is hamlbars
https://github.com/jamesotron/hamlbars which provides some helper
methods, and my own academic experiments in extending haml in a
similar fashion here: https://github.com/duncanbeevers/haml-ejs

That said, many client-side templating languages use different or
customizable delimiters, and support different subsets of javascript
within the templates, from full-js-interpretation all the way down to
only-top-level-properties-of-a-single-data-object, and extending haml
to deal with all of these is pretty much guaranteed to only serve a
subset of the needs programmers will have down the line.

haml itself is already a member of the school of templating languages
that provide access to the full functionality of the ruby interpreter
within the template. Adding extra delimiters means a human looking
over a templates needs to mentally parse two to three languages just
to figure out what's going on.

Is haml the way forward? Should it be re-plumbed to make adding custom
delimiters part of its public API? Should it embrace generation of
client-side templates and include first-class support for this new
family of consumers?

I don't know. So far, using haml for these purposes has been a mixed
bag. The results have been great, but the friction on the way has not
been pleasant.

Bernie

unread,
Apr 22, 2012, 11:13:02 PM4/22/12
to ha...@googlegroups.com
Upon more thinking, using the "^" as a delimiter may be exactly what we need, with the caveat that users might want to specify in a configuration option, which delimiters to use. For example, a user might pick from [:ejs, :handlebars, :mustache,...].

Duncan Beevers

unread,
Apr 22, 2012, 11:21:29 PM4/22/12
to ha...@googlegroups.com
Feel free to crib or gut the haml-ejs work as you see fit.

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

> To view this discussion on the web visit
> https://groups.google.com/d/msg/haml/-/w9UJnuQWDngJ.

Bernie

unread,
Apr 24, 2012, 12:45:44 AM4/24/12
to ha...@googlegroups.com
Great! I've started (slowly) extracting ejs-specific stuff in the javascript_support of my haml repo (http://github.com/btelles/haml.git)
Can't guarantee that this'll be done anytime soon, but I'll give it a try.

Maintainers of HAML, if I submit a pull request, would you be willing to pull it in?

Bernie

Jordon Bedwell

unread,
Apr 22, 2012, 5:27:45 AM4/22/12
to ha...@googlegroups.com

At the same time it's a good idea it's a bad idea. You can already do:

%table
%tbody
-MyApp.MyArray.each
%tr
%td=some_value
%tfood

Bernie

unread,
Apr 24, 2012, 4:53:33 PM4/24/12
to ha...@googlegroups.com
Jordan, I'm not sure I understand...isn't that just the Ruby way to do the same thing? How would that look on the client side?

Hampton

unread,
Apr 24, 2012, 5:05:50 PM4/24/12
to ha...@googlegroups.com
I'd have to say that I don't clearly understand why we'd use this delimiter? It would
break existing code... what if that appeared naturally in your Haml?

The recommended way is either.

.span #{myvar}
.span= myvar

I have no personal problem with {{_}}, but what does it have that is so much better than #{_} that
would be useful for these purposes?

Now, there is a bigger question being breached here, which is Haml's relationship to client-side
scripts... I have to say I have mixed feelings on this topic in a general sense. Seems like Haml
would be a bad fit... unless you used Haml to *generate* some JS that was the proper template
you were looking for. But, structured, semantic html is something that is already implicit in well
defined JS data structures... aka,

{name: {first_name: "hampton", last_name: "catlin"}}

can easily be converted to

<div class="name"><div class="first">hampton</div>.... blah, blah i hate typing, but you get it

I'm not sure how much advantage Haml gives in a data=>template transformation which is the
primary usage of Moustache&co. 

Haml focuses on document layout and structure. Which does have some overlap, but not enough
in my mind.

I do have some thoughts recently on things I want to see get added to Haml, but I'd have to say this isn't
one of them.

-hampton.

On Tue, Apr 24, 2012 at 3:53 PM, Bernie <bte...@gmail.com> wrote:
Jordan, I'm not sure I understand...isn't that just the Ruby way to do the same thing? How would that look on the client side?

--
You received this message because you are subscribed to the Google Groups "Haml" group.
To view this discussion on the web visit https://groups.google.com/d/msg/haml/-/h9M7fHBAFiUJ.

Bernie

unread,
Apr 24, 2012, 10:30:55 PM4/24/12
to ha...@googlegroups.com
Thanks for chiming in Hampton:

I'm not sure we (the for-delimiter folks) are explaining ourselves very well. First, I think we more or less agree that the best delimiter would be the hat character "^". The {{_}} simply remained the title of the first email, even though we agree it doesn't fit the bill.

The second question that you raised is much closer to our concerns (Duncan, I hope I'm not overstepping by saying 'we').

>> unless you used Haml to *generate* some JS that was the proper template you were looking for...

That's precisely what we are trying to do. Here's a quick example:

%h1 {{ MyJsVar.thatIsPlainText }}

On the client side, the haml would resolve to:

<h1>{{ MyJsVar.thatIsPlainText }}</h1>

This already works, and haml does not need to change to handle this case...the template is just plain text that gets rendered out. But something a little more complex, like 'block' templates, would need some additions:

^if myVar > yourVar
  %h1 {{ myVar }}
  ^else                                  # I always forget whether we should indent the 'else' in regular haml.
    %h2 {{ yourVar }}

The above might resolve to the following in Handlebars:

{{#if myVar > yourVar }}
  <h1> {{ myVar }} </h1>
{{#else}}
  <h2> {{ yourVar }} </h2>
{{/if}}

And it would look like this with Ejs:

<% if( myVar > yourVar ) { %>
  <h1> <%= myVar %> </h1>
<% } else { %>
  <h2> <%= yourVar %> </h2>
<% } %>

The advantage is that people can keep the indentation, succinctness, and (I would say) semantic meaning provided by haml, to write client-side templates. I'll try and refrain myself from pestering you with this idea any further...just wanted to make sure we are on the same page before you decide it really doesn't fit. I'd be happy to answer any more questions though.

Cheers,
Bernie

Duncan Beevers

unread,
Apr 25, 2012, 8:22:41 AM4/25/12
to ha...@googlegroups.com
I originally wanted to simply retarget haml so that it generated
javascript templates rather than invoking the Ruby interpreter. Just
as Hampton mentions, the canonical way to output a variable would be.

%span= username

In the current implementation, the result of compiling this would be
something like:
<span>duncan</span>

Retargeted, I imagined haml outputting something like this instead:

<span>{{username}}</span>

But I found that I still needed and wanted access to pieces of the
Ruby environment like configuration values, url-generation methods,
and markup-generating methods like link_to. Faced with the trade-off,
I elected to extend the semantics of haml to make it easy to generate
the kinds of simple expressions in wanted in my client-side templates
while continuing to express myself using the elegant style haml
brought to the Ruby in my templates.

Right now, in order to generate simple mustache conditional I have to
jump through a few hoops.

In an ideal world I'd write:
%p
{{#sunny}}
My kind of weather

But mustache ain't haml, so I have to close the block myself. However,
because of haml's indentation rules, I can't just write this:

%p
{{#sunny}}
My kind of weather
{{/sunny}}

So I have a couple of options. I can either write this:

%p
:text
{{#sunny}}
My kind of weather
{{/sunny}}

Or this:

%p
{{#sunny}}My kind of weather{{/sunny}}

I wanted haml's indentation awareness to make the loops and
conditionals in my templates feel like coffeescript, and like haml
itself, without having to give up (read, change or modify) the bits of
template I'd written that relied on Ruby.

As far as the specific sigils I introduced, I knew I wanted more
control over the generated output than I would get targeting mustache
which can do a number of different things when it encounters a sigil
like {{#, such as performing a conditional check, invoking a function,
or looping over a collection of values. Instead, I had
explicitly-specified output for the specific pieces of functionality I
wanted to allow the client-side template access to.

I never opened a pull request for this because I never believed it was
something that belonged in haml core. I feel the first approach was
likely to get bound up in painful compromises trying to effectively
translate Ruby to JavaScript/template dialect, and my approach changes
the semantics of haml in a backwards-incompatible way.

Reply all
Reply to author
Forward
0 new messages